# Webflow

> Webflow の Form Block を独自の action で Ikiform に送信し、短いスクリプトで Webflow の成功・エラー表示を残し、webflow.io のステージングサイトを許可します。

Webflow の Form Block は任意の URL に送信できます。action を Ikiform のエンドポイントに向ければ、Designer で作ったレイアウトとスタイルはそのままに、Ikiform がバリデーション、スパムの除外、保存、メール通知、Webhook の送信を行います。

## 独自の action で変わること

- Webflow がフォームを処理するのは、Webflow 自身が送信先の場合だけです。独自の action ではブラウザーが Ikiform に直接送信するので、送信データは Webflow のフォーム送信一覧に表示されず、Webflow から通知メールも届きません。
- Webflow 自身の送信先は、独自の action と同時には使えません。Ikiform を追加する前に、**Send to** で削除してください。
- Webflow は結果を受け取らないため、Webflow の成功ブロックとエラーブロック（`.w-form-done` と `.w-form-fail`）や、フォーム自体のリダイレクト設定は動かなくなります。訪問者は Ikiform のサンクスページか、**Redirect after submit**（送信後のリダイレクト）の URL に移動します。[ステップ 4](#keep-success-state) で Webflow のブロックを復活させられます。

## フォームを設定する

### ステップ 1: フォームの送信先を Ikiform にする

Form Block 内のフォームを選択し、**Settings** パネルを開きます。**Send to** で独自の action を選び、**Action** にエンドポイントを貼り付け、**Method** を **POST** にします。

`Action`:

```text
https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx
```

メソッドを GET のままにすると、ブラウザーはエンドポイントをページとして開き、`404 not_found` が返ります。Ikiform は POST しか受け付けません。

### ステップ 2: フィールドに名前を付ける

各入力欄の **Name** 設定が、Ikiform でのフィールド名になります。Webflow はラベルから自動で入力するので、`Name`、`Email`、`Field 2` のような名前になります。`name`、`email`、`message` など、表示したい ID に変更してください。

- Ikiform のフォームで[フィールド](https://ikiform.com/ja/docs/fields.md)を定義する場合、名前はその ID と完全に一致させる必要があります。ID は小文字の snake_case なので、`Email` と `email` は別のフィールドです。
- フォームに reCAPTCHA 要素があれば削除してください。Ikiform はそれを検証せず、`g-recaptcha-response` の値が余分なフィールドとして届いてしまいます。代わりに Ikiform の[スパムチェック](https://ikiform.com/ja/docs/spam.md#human-check)を使ってください。

### ステップ 3: ハニーポットを追加する

フォームに Input を追加し、**Name** を `_gotcha` にして、Style パネルの **Display: none** で非表示にします。**Custom attributes** で `tabindex` を `-1`、`autocomplete` を `off` に設定すると、キーボードやパスワードマネージャーが飛ばすようになります。有料のサイトプランなら、代わりにフォーム内の Code Embed にこれを貼り付けることもできます:

`Code Embed`:

```html
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
```

### ステップ 4: 送信後の動作を選ぶ

いちばん簡単なのはサンクスページです。Webflow でページを作って公開し、その完全な URL を Ikiform のフォーム設定の **Redirect after submit**（送信後のリダイレクト）に貼り付けます。

### Webflow の成功ブロックとエラーブロックを残す

ページにとどまるには、`fetch` で送信し、Webflow のブロックを自分で切り替えます。これを **Page settings** > **Custom code** > **Before </body> tag** に貼り付けるか、すべてのフォームに適用するならサイトのフッターコードに貼り付けます。Ikiform のエラーメッセージをエラーブロック内に表示し、送信中はボタンの **Waiting text** を使います。

`Before </body> tag`:

```html
<script>
  document.querySelectorAll('form[action^="https://ikiform.com/f/"]').forEach((form) => {
    const wrapper = form.closest(".w-form");
    const done = wrapper?.querySelector(".w-form-done");
    const fail = wrapper?.querySelector(".w-form-fail");
    const button = form.querySelector('[type="submit"]');

    form.addEventListener("submit", async (event) => {
      event.preventDefault();
      const label = button?.value;
      if (button) {
        button.disabled = true;
        button.value = button.dataset.wait || label;
      }
      try {
        const response = await fetch(form.action, {
          method: "POST",
          headers: { Accept: "application/json" },
          body: new FormData(form),
        });
        const result = await response.json();
        if (result.ok) {
          form.style.display = "none";
          if (fail) fail.style.display = "none";
          if (done) done.style.display = "block";
          return;
        }
        const text = fail?.querySelector("div") ?? fail;
        if (text) text.textContent = result.error.message;
        if (fail) fail.style.display = "block";
      } catch {
        if (fail) fail.style.display = "block";
      } finally {
        if (button) {
          button.disabled = false;
          button.value = label;
        }
      }
    });
  });
</script>
```

> カスタムコードと Code Embed 要素には、有料のサイトプランまたは Workspace プランが必要で、どちらも Designer では動きません。動作を確認するには公開してください。

このスクリプトは `fetch` で送信するため、スパムチェックが **Ikiform** のフォームでは確認ページが表示されず、`403 challenge_required` が返ります。チェックをオフにしてスクリプトを使うか、スクリプトを使わずにブラウザーに通常どおり送信させてください。後者なら追加のコードなしでチェックが動きます。

## 許可ドメイン

許可ドメインを設定する場合は、フォームを公開するすべてのアドレスを登録してください。登録したドメインのサブドメインは自動的に一致します。

| フォームが動く場所 | 許可ドメインに追加するもの |
| --- | --- |
| 独自ドメイン | `example.com`（`www.example.com` も含まれます） |
| Webflow のステージング | `your-site.webflow.io` |
| Designer のキャンバス | 不要です。独自の action やカスタムコードはそこでは動きません。 |

- `webflow.io` だけを追加しないでください。他の人のサイトも含め、そのホスト上のすべてのサイトが一致してしまいます。

## テストのチェックリスト

1. `webflow.io` のステージングドメインに公開します。独自の action を持つフォームは、公開されたサイトからしか送信されません。
2. フォームを送信し、Ikiform でフォームの送信データを開きます。新しい送信データが、スパムではなく受信済みとして表示されているはずです。
3. フィールド名がステップ 2 で設定したものと一致しているか、ハニーポットが表示されていないかを確認します。`_` で始まる名前は保存されません。
4. サンクスページに移動するか、スクリプトを追加した場合は Webflow の成功ブロックが表示されることを確認します。
5. 独自ドメインに公開し、そこからもう一度送信します。

## トラブルシューティング

| 症状 | 原因 | 対処 |
| --- | --- | --- |
| 送信後に `404 not_found` のページが表示される | **Method** が GET なので、ブラウザーがエンドポイントをリンクのように開いた | **Method** を **POST** にして、もう一度公開します。 |
| Webflow の成功メッセージではなく Ikiform のサンクスページが表示される | Webflow の成功ブロックは、Webflow がフォームを処理する場合にしか動かない | **Redirect after submit**（送信後のリダイレクト）を設定するか、ステップ 4 のスクリプトを追加します。 |
| 送信データが `origin_mismatch` でスパムフィルターの下に届く | 送信したページが、フォームの許可ドメインに含まれていない | 上の表のホストを追加します。**Reject** を選んでいる場合、同じ送信には代わりに `403 origin_not_allowed` が返ります。 |
| Unknown field を示す `422 validation_failed` | `Email` や `g-recaptcha-response` などのフィールド名が、フォームのフィールド定義にない | 入力欄の名前をフィールド ID に変更するか、reCAPTCHA 要素を削除します。 |
| スクリプトが何もしない | Designer でテストしている、サイトに有料プランがない、または action が `https://ikiform.com/f/` で始まっていない | 公開されたサイトでテストし、**Action** に空白が入っていないか確認します。 |
| エラーブロックに `Complete the human check, then send the form again.` と表示される | スパムチェックが **Ikiform** に設定されていて、スクリプトが `fetch` で送信している | このフォームのチェックをオフにするか、スクリプトを削除します。 |

## 関連ページ

- [サイトビルダー](https://ikiform.com/ja/docs/guides/site-builders.md): どのビルダーでも使える埋め込み。
- [HTML フォーム](https://ikiform.com/ja/docs/html.md): リダイレクト、予約済みフィールド、ハニーポット。
- [許可ドメイン](https://ikiform.com/ja/docs/spam.md#allowed-domains): オリジンの照合方法と、一致しない場合の動作。
- [エラー](https://ikiform.com/ja/docs/errors.md): すべてのエラーコードと、その原因と対処。
