最小の形
項目だけ書きます。送信処理・hidden 項目・エラー表示の JavaScript は要りません(script タグ は入れておきます)。
<form data-sitekit-form="contact">
<label>お名前 <input name="name" required autocomplete="name"></label>
<label>メール <input type="email" name="email" required autocomplete="email"></label>
<label>お問い合わせ内容 <textarea name="message"></textarea></label>
<!-- ボット対策。人には見えない場所に置く(必須) -->
<input type="text" name="_hp" tabindex="-1" autocomplete="off"
style="position:absolute;left:-9999px" aria-hidden="true">
<button type="submit">送信する</button>
</form>
<div data-sitekit-success role="status" aria-live="polite" hidden>お問い合わせありがとうございました。</div>
<div data-sitekit-error role="status" aria-live="polite" hidden></div>名前を合わせる
| HTML | schema.json |
|---|---|
data-sitekit-form="contact" の contact | forms[].key |
入力の name="email" | その form の fields[].key |
- schema.json に無いフォームのキーは
not_foundになります - schema.json に無い
nameはエラーにならず、保存もされません requiredの項目は、空だとinvalid_requestになります(項目ごとの文字数などの制約は schema.json の型)
ハニーポット(_hp)は必ず入れる
name="_hp" の入力は、人には見えないボット対策の欄です。ここが埋まっている送信は保存されません。ただしボットに気づかせないため、画面上は成功と同じに見えます。
tabindex="-1"とautocomplete="off"を付け、画面の外に置きます(ブラウザの自動入力で埋まらないように)- schema.json には書きません
成功・エラーの表示
[data-sitekit-success] と [data-sitekit-error] は、フォームの中か、フォームと同じ親要素の直下に置きます。
- 成功するとフォームが
hiddenになります。成功の文言はフォームの外に置きます(中に置くと一緒に隠れる) role="status" aria-live="polite"を付けます。付けないと、送信後に出た文言がスクリーンリーダーに読み上げられません- エラーのときは
[data-sitekit-error]に次の文言が入ります
| 状況 | 表示される文言 |
|---|---|
入力の誤り(invalid_request) | 入力内容をご確認ください |
短時間に送りすぎ(rate_limited) | しばらく経ってからお試しください |
Turnstile の確認に失敗(turnstile_failed) | 確認に失敗しました。もう一度お試しください |
| 通信できない | 送信できませんでした。通信環境をご確認ください |
| そのほか | 送信できませんでした。時間をおいてお試しください |
入力の誤りのときは、該当する項目に aria-invalid="true" が付きます。見た目はサイト側の CSS で当てます。
[aria-invalid="true"] { border-color: #c00; }送信後に別ページへ移動する
<form data-sitekit-form="contact" data-success-url="/thanks/">同じオリジンのページだけです。別のオリジンへ移動するときは、明示して許可します。
<form data-sitekit-form="reserve"
data-success-url="https://booking.example.com/done"
data-success-external="1">スキームやポートが違えば別オリジンです。javascript: と data: は data-success-external を付けても移動しません。
二重送信の防止
連打や、入力欄での Enter による再送信は自動で止めます。送信中は送信ボタンが disabled になり、<form> に aria-busy="true" が付きます。form="フォームのid" でフォームの外に置いた送信ボタンにも効きます。
複数の値を持つ項目は使えない
チェックボックスの群や <select multiple> など、同じ name を複数使うと最後の値だけが送られます。複数の答えが要る質問は、キーを分けます。
<!-- NG: topic が1つしか届かない -->
<input type="checkbox" name="topic" value="a">
<input type="checkbox" name="topic" value="b">
<!-- OK -->
<input type="checkbox" name="topic_a" value="1">
<input type="checkbox" name="topic_b" value="1">Turnstile
Cloudflare Turnstile のウィジェットが作る cf-turnstile-response の入力があれば、自動で一緒に送ります。サイト側で特別な記述は要りません。
通知
お問い合わせは保存された時点で確定します。通知はそのあとに送られ、どの通知が失敗してもお問い合わせは消えません。各通知の成否は管理画面のお問い合わせの詳細に出て、失敗したものは再送できます。
通知先は schema.json ではなく、管理画面の「設定」→ 各フォームで、サイトのオーナーが変えます。
| 通知 | 設定するもの |
|---|---|
| お店へのメール | お知らせ先のメールアドレス(複数可) |
| Slack | Incoming Webhook の URL(Slack でアプリを作り、投稿先チャンネルを選んで発行する) |
| スプレッドシートへの記録 近日 | 外部のアカウントへの開放は準備中です |
- 通知ごとにオン・オフを切り替えられます
- Slack の Webhook URL は、持っている人が誰でもそのチャンネルに投稿できる鍵です。管理画面は伏せ字で表示し、API も返しません。URL を失くしたら Slack で発行し直します
- 設定を変えられるのはオーナーだけです(スタッフは見るだけ)
お礼メール(自動返信)と差し込み変数
お客様へのお礼メールは、次のときに送られます。
- 管理画面の設定で、そのフォームの「お礼メール」がオン
- そのフォームに
type: "email"の項目があり、値が入っている
件名と本文は設定画面で書きます(プレビューあり)。差し込める変数:
| 変数 | 中身 |
|---|---|
{{name}} {{email}} など | フォームの項目の値(項目の key そのまま) |
{{site_name}} | サイト名 |
{{form_label}} | フォームの名前(forms[].label) |
{{submitted_at}} | 送信日時 |
{{name}} 様
{{site_name}} へのお問い合わせありがとうございます。
内容を確認のうえ、ご連絡いたします。
受付日時: {{submitted_at}}送信を GTM で拾う
送信が成功したときだけ、dataLayer に次が積まれます。
{ event: "sitekit_form_submit", form: "contact" }formはdata-sitekit-formに書いたキーです- イベント名は管理画面の「設定 → 各フォーム → 完了イベント名」で変えられます。サイトの再デプロイは要りません。名前を変えたら GTM のトリガーも直します(古い名前のトリガーは黙って動かなくなります)
- ハニーポットで弾いた送信も画面上は成功なので、このイベントは積まれます。実際に届いた件数は管理画面の一覧で数えます
GTM 側は、トリガー「カスタム イベント」のイベント名に上の名前を入れ、フォームで分けたいときはデータレイヤーの変数 form を条件にします。
テスト送信
いちばん確かなのは、公開したページ(開発用ドメインでもよい)から実際に送ることです。API に直接送ることもできます。
curl -s -X POST -H 'content-type: application/json' \
-d '{"name":"テスト","email":"test@example.com","message":"テスト送信です"}' \
https://cdn.sitekit.example/v1/sites/hanaya/forms/contact
# => {"ok":true,"id":"...","gtm_event":"sitekit_form_submit"}テストでも本物のお問い合わせとして保存され、通知も届きます。 件数の上限にも数えられます。試したあとは管理画面から消してください。CLI の forms test は準備中です 近日。
流入元(UTM)の記録
script が覚えておいた流入元(最初に来たときと最後に来たときの utm_* / gclid / fbclid・着地ページ・参照元)が、送信のたびに自動で添えられ、お問い合わせと一緒に保存されます。サイト側の作業はありません(script タグ)。
受付の上限
フォームの受付件数はプランごとに上限があります(Dev は通算、有料プランは月ごと)。上限に達したときの動きは プランと上限 にあります。