React
送信中、エラー、成功の状態、フィールドエラー、任意の人間確認を備えた React のフォーム。
Vite、Remix、React Router、Gatsby、Next.js のクライアントコンポーネントなど、どんな React アプリでも動きます。ブラウザーから直接送信するので、レート制限は訪問者ごとにカウントされます。
SDK をインストールする
npm install @ikiform/sdk完全なフォーム
import { challenge, submit } from "@ikiform/sdk";
import { useState } from "react";
const FORM_ID = "frm_xxxxxxxxxxxxxxxx";
export function ContactForm({ humanCheck = false }) {
const [status, setStatus] = useState("idle");
const [errors, setErrors] = useState({});
const [message, setMessage] = useState("");
async function onSubmit(event) {
event.preventDefault();
const data = new FormData(event.currentTarget);
setStatus("sending");
setErrors({});
try {
const turnstileToken = humanCheck ? await challenge(FORM_ID) : undefined;
const result = await submit(FORM_ID, data, { turnstileToken });
if (result.ok) return setStatus("sent");
setErrors(result.error.fields ?? {});
setMessage(result.error.message);
} catch {
setMessage("The human check didn't finish. Try again.");
}
setStatus("error");
}
if (status === "sent") return <p>Thanks, we got it.</p>;
return (
<form onSubmit={onSubmit}>
<label>
Email
<input name="email" type="email" required />
</label>
{errors.email ? <p>{errors.email[0]}</p> : null}
<label>
Message
<textarea name="message" />
</label>
{errors.message ? <p>{errors.message[0]}</p> : null}
<input name="_gotcha" type="text" tabIndex={-1} autoComplete="off" hidden />
{status === "error" && message ? <p role="alert">{message}</p> : null}
<button disabled={status === "sending"}>Send</button>
</form>
);
}- フォームのスパムチェックが Ikiform の場合は
humanCheckを渡します。チェックがオフなら省略します。 - チェックが失敗または中断されると、
challengeはChallengeErrorで reject され、catchでメッセージに変換されます。 - SDK を使わない場合は、JavaScript と fetch のように
submitをfetchに置き換えます。
フォームアクションとして使う
React 19 では、submit が返す値はフォームアクションの型も満たすので、そのまま action に渡せます。React 内部の $ACTION_ フィールドは送信前に除外されます。
import { submit } from "@ikiform/sdk";
export function Newsletter() {
return (
<form action={(data) => submit("frm_xxxxxxxxxxxxxxxx", data)}>
<input name="email" type="email" required />
<button>Subscribe</button>
</form>
);
}送信前にバリデーションする
validate は 12 種類すべてのフィールドタイプで、サーバーと同じルールとメッセージを使うので、リクエストの前にエラーを表示できます。正とするのはあくまでサーバーです。
import { getSchema, validate } from "@ikiform/sdk";
const schema = await getSchema("frm_xxxxxxxxxxxxxxxx");
function check(form) {
if (!schema.ok) return {};
return validate(schema.schema.fields, new FormData(form));
}