# Wix

> Wix はカスタム HTML を、ページを遷移できないサンドボックス化されたフレームで実行するため、fetch で送信する HTML フォームを Wix のサイトに埋め込みます。

Wix Forms は送信データを Wix 内に保存し、外部の action URL を設定する項目はありません。Ikiform を使うには、自分のフォームを **Embed HTML** 要素に置きます。Wix はそのコードを、別の `filesusr.com` ホストから配信されるサンドボックス化された iframe の中で実行します。以下の内容はすべてこの前提に基づいています。

## フォームを fetch で送信する理由

- Wix のフレームはフォーム、スクリプト、ポップアップ、同一オリジンへのアクセスを許可しますが、トップレベルのページ遷移は許可しません。`target="_top"` で訪問者をサンクスページに移動させることはできません。
- 通常のフォーム送信では、小さなフレームの中に結果が読み込まれますが、Ikiform のサンクスページ、エラーページ、確認ページはフレーム内での表示を拒否します。訪問者には空のフレームか、拒否されたフレームが表示されてしまいます。
- `fetch` と `Accept: application/json` で送信すれば、訪問者はその場にとどまり、結果は埋め込みの中に表示されます。

## 埋め込みを追加する

### ステップ 1: Embed HTML 要素を追加する

Wix エディターで **Add Elements** > **Embed Code** > **Embed HTML** を開きます。Wix Studio では **Embed & Social** にあります。**Website address** ではなく **Code** を選びます。

### ステップ 2: フォームを貼り付ける

`Embed HTML`:

```html
<form id="contact" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post" novalidate>
  <label>Email <input name="email" type="email" autocomplete="email" required /></label>
  <p class="error" data-error-for="email"></p>
  <label>Message <textarea name="message" rows="4"></textarea></label>
  <p class="error" data-error-for="message"></p>
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send</button>
  <p role="status" data-status></p>
</form>

<script>
  const form = document.querySelector("#contact");
  const button = form.querySelector("button");
  const status = form.querySelector("[data-status]");

  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    button.disabled = true;
    status.textContent = "Sending";
    try {
      const response = await fetch(form.action, {
        method: "POST",
        headers: { Accept: "application/json" },
        body: new FormData(form),
      });
      const result = await response.json();
      const fields = result.ok ? {} : result.error.fields ?? {};
      for (const slot of form.querySelectorAll("[data-error-for]")) {
        slot.textContent = fields[slot.dataset.errorFor]?.[0] ?? "";
      }
      status.textContent = result.ok ? "Thanks, we got it." : result.error.message;
      if (result.ok) form.reset();
    } catch {
      status.textContent = "Couldn't reach the server. Try again.";
    } finally {
      button.disabled = false;
    }
  });
</script>

<style>
  body { margin: 0; font: 15px/1.5 system-ui, sans-serif; }
  form { display: grid; gap: 8px; }
  label { display: grid; gap: 4px; }
  input, textarea, button { font: inherit; padding: 8px 10px; border: 1px solid #d4d4d4; border-radius: 6px; }
  button { background: #111; color: #fff; border: 0; }
  .error { margin: 0; color: #b42318; font-size: 13px; }
</style>
```

フレームはサイトのフォントや色を引き継がないので、`<style>` ブロックで設定しています。サイトに合わせて変更してください。

### ステップ 3: サイズを調整して公開する

フィールドエラーとステータス行が収まる高さまで要素を広げてから公開します。エディターではカスタムコードのプレースホルダーしか表示されないので、公開されたサイトでテストしてください。

> Wix のサイト全体の **Custom Code** 設定（プレミアムプランと接続済みのドメインが必要）は、ページの head や body にコードを追加します。レイアウト内の特定の位置にフォームを置くことはできないので、フォーム自体を置く場所はやはり Embed HTML 要素です。

## スパムの設定

フォームのスパムチェックはオフのままにします。Ikiform の人間確認には、確認ページか小さな ikiform.com のフレームが必要ですが、どちらも Wix のサンドボックス内では動きません。ハニーポットとスパムスコアは、すべての送信で引き続き動きます。

## 許可ドメイン

送信は iframe の中から送られるため、Ikiform が認識するのは Wix のドメインではなく、フレームのホストです。確認するには、公開されたページを開いて埋め込みを検証し、iframe の `src` を読み取ります。

| フォームが動く場所 | 許可ドメインに追加するもの |
| --- | --- |
| 埋め込みのフレーム | iframe の `src` に書かれた正確なホスト（`www-example-com.filesusr.com` など） |
| Wix のドメインまたは独自ドメイン | 埋め込みには不要です。送信がそこから来ることはありません |

- `filesusr.com` だけを追加しないでください。他の人のサイトも含め、そのホスト上のすべてのサイトが一致してしまいます。
- フレームのホストはサイトのアドレスから決まるので、新しいドメインを接続すると変わります。ドメインを変更したら、もう一度確認してください。

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

1. 公開し、プライベートウィンドウで本番のページを開きます。
2. [フィールド](https://ikiform.com/ja/docs/fields.md)を定義している場合は、メールアドレスを空にして送信します。フォームには `novalidate` が付いているので、Ikiform のメッセージがフィールドの下に表示されるはずです。
3. 本物のメッセージを送信し、ステータス行に "Thanks, we got it." と表示され、送信データが Ikiform に表示されることを確認します。
4. フレームのホストで許可ドメインをオンにして、もう一度送信します。引き続き受信済みに届くはずです。

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

| 症状 | 原因 | 対処 |
| --- | --- | --- |
| 送信後に埋め込みが空白になる、または拒否されたページが表示される | スクリプトが動かなかったため、ブラウザーが通常どおり送信し、フレーム内で Ikiform のページを読み込もうとした | スクリプトが要素に入っているか、フォームの id が `contact` になっているかを確認します。 |
| 送信データが `origin_mismatch` でスパムに届く | フレームのホストが許可ドメインにない、または代わりに Wix のドメインを登録している | iframe の `src` にある正確な `filesusr.com` のホストを追加します。 |
| ステータス行に `Complete the human check, then send the form again.` と表示される | スパムチェックが **Ikiform** に設定されているが、サンドボックス内では動かない | このフォームのチェックをオフにします。 |
| ステータス行に、サーバーに接続できなかったと表示される | 広告ブロッカーやネットワークのフィルターがリクエストをブロックした。`filesusr.com` 自体をブロックするネットワークもあります。 | 別のネットワークか、拡張機能のないプライベートウィンドウでテストします。 |
| エラーメッセージが途中で切れる | 要素の高さがフォームより低い | エディターで要素を高くします。 |

## 関連ページ

- [素の JavaScript](https://ikiform.com/ja/docs/guides/javascript.md): インラインエラー付きの `fetch`。
- [サイトビルダー](https://ikiform.com/ja/docs/guides/site-builders.md): どのビルダーでも使える埋め込み。
- [許可ドメイン](https://ikiform.com/ja/docs/spam.md#allowed-domains): オリジンの照合方法と、一致しない場合の動作。
- [スパム対策](https://ikiform.com/ja/docs/spam.md): ハニーポット、スコアリング、人間確認。
