# 自分で作った結婚式サイトに置く出欠フォーム

> 自作の結婚式サイト用の出欠フォーム。招待ごとに 1 回答、名前のあるゲストごとに料理を選び、締め切りと未回答者のリストも用意します。

公開日 2026-10-25 · https://ikiform.com/ja/guides/event-registration/wedding-rsvp

招待ごとに、招待コードとゲストの名前を含む専用の出欠リンクを用意し、フォームにゲストごとの名前と料理の選択肢を表示させます。回答はすべて Ikiform に送信されるので、回答ごとにメールが届き、ケータリング業者に渡す CSV も手に入ります。スプレッドシートで回答をゲストリストと照らし合わせて未回答者を確認し、締め切り後はフォームを一時停止します。

## 結婚式ならではの違い

ミートアップでは見知らぬ人を数えます。結婚式では、すでにあるゲストリストを招待ごとに数えます。そこから 4 つのことが導かれます:

- **回答は 1 人ごとではなく招待ごとに 1 つ。** 夫婦や家族はまとめて回答します。
- **同伴者数ではなく、名前のあるゲスト。** 招待したのは Ada と Sam であって、`2` ではありません。同伴者は招待状に書かれているか、いないかのどちらかです。
- **1 人ずつの料理。** ケータリング業者には、魚、牛肉、ベジタリアンの合計と、お子さま用の皿数が必要です。
- **厳格な締め切りと督促リスト。** 会場は期日までに人数を求めます。役に立つのは、まだ回答していない人のリストです。

Zola、The Knot、Joy などの結婚式サイトサービスには、ゲストリストを中心にした、名前で検索できる出欠ツールがあります。そのどれかでサイトを作っているなら、その出欠機能を使ってください。このページは、Squarespace、Carrd、Framer、プレーンな HTML などで自作した結婚式サイトで、出欠を自分のページに置きたい場合のためのものです。

Ikiform にはゲストリストの検索も繰り返しグループもないので、フォームだけでは招待に誰が含まれるかを知ることができません。コツは、その情報をリンクに入れることです。

図: 専用の出欠リンクで、ゲストリストからケータリングの数まで

1. ゲストリストのシートには招待ごとに 1 行があり、短いコード、世帯名、ゲストの名前が入っています。
2. 数式で各行を、コードと名前を含む専用の出欠リンクに変換します。
3. リンクは QR コードとして招待状に印刷するか、メッセージで送ります。
4. 出欠ページがリンクを読み、ゲストごとに名前と料理の選択肢を 1 つずつ表示してから、Ikiform に送信します。
5. 回答を CSV でエクスポートし、ゲストリストの隣にインポートします。
6. コードを照合すると未回答の招待がわかるので、誰に連絡すべきかがわかります。
7. 回答全体で料理ごとに数えると、ケータリング業者に伝える合計になります。

ゲストリストはシートに残ります。リンクが運ぶのは、フォームを個人向けにするのに必要な分だけです。

## 招待ごとにリンクを作る

ゲストリストのシートで、A 列に `okafor` や `nguyen-family` のような短いコード、B 列に世帯名、C 列にゲストのファーストネームをカンマ区切りで入れます。D 列のこの数式でリンクを作ります:

`ゲストリスト、D 列`:

```text
="https://ada-and-sam.example/rsvp?party=" & A2 & "&names=" & ENCODEURL(C2)
```

各リンクを QR コードとして招待状に印刷するか、メッセージに貼り付けます。コードは小文字とハイフンだけにしてください。フィールドのパターンはそれ以外を拒否するので、打ち間違えたコードを早めに見つけられます。

## フォーム

これを結婚式のページか、ビルダーの埋め込みブロックに貼り付けます。リンクから `party` と `names` を読み、ゲストごとに名前と料理の行を最大 4 つまで追加し、締め切り後は自身を非表示にします。リンクに名前がなければ、入力用の行を 1 つ表示します。

`rsvp.html`:

```html
<form id="rsvp" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <input type="hidden" name="party" id="party">
  <div id="guests"></div>
  <label>Email for updates <input name="email" type="email" autocomplete="email" required></label>
  <label>A song that gets you dancing <input name="song" maxlength="120"></label>
  <label>Anything we should know? <textarea name="note" rows="3" maxlength="1000"></textarea></label>
  <input type="hidden" name="_redirect" value="https://ada-and-sam.example/thank-you">
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <button type="submit">Send our RSVP</button>
</form>
<p id="closed" hidden>RSVPs closed on 1 May. Message us if your plans have changed.</p>

<template id="guest-row">
  <fieldset>
    <legend></legend>
    <label>Name <input data-part="name" maxlength="80" autocomplete="off"></label>
    <label>Meal
      <select data-part="meal">
        <option value="beef">Beef</option>
        <option value="fish">Fish</option>
        <option value="vegetarian">Vegetarian</option>
        <option value="child">Child's menu</option>
        <option value="not_coming">Can't come</option>
      </select>
    </label>
  </fieldset>
</template>

<script>
  const DEADLINE = new Date("2027-05-01T23:59:00+01:00");
  const params = new URLSearchParams(location.search);
  const party = (params.get("party") ?? "").toLowerCase();
  const names = (params.get("names") ?? "").split(",").map((name) => name.trim()).filter(Boolean).slice(0, 4);
  const rsvp = document.getElementById("rsvp");

  if (Date.now() > DEADLINE.getTime()) {
    rsvp.hidden = true;
    document.getElementById("closed").hidden = false;
  } else {
    document.getElementById("party").value = party;
    const rows = names.length ? names : [""];
    rows.forEach((name, index) => {
      const n = index + 1;
      const row = document.getElementById("guest-row").content.cloneNode(true);
      row.querySelector("legend").textContent = name || "Your name";
      const input = row.querySelector('[data-part="name"]');
      input.name = `guest_${n}_name`;
      input.value = name;
      input.required = n === 1;
      row.querySelector('[data-part="meal"]').name = `guest_${n}_meal`;
      document.getElementById("guests").append(row);
    });
  }
</script>
```

- 各ゲストの料理には `Can't come` が含まれるので、世帯の 1 人が来られない場合でも回答は 1 つで済みます。
- 名前の入力欄はあらかじめ埋まっていますが編集できるので、ゲストが綴りを直したり子どもの名前を書いたりできます。
- フォームは通常の方法で送信し、`_redirect` でサンクスページに移動します。そこに日付、会場、カレンダーへのリンクを載せてください。Ikiform はゲストにメールを送りません。
- 締め切りはブラウザーでフォームを隠すだけです。締め切り日には Ikiform でも **Pause form** を選び、保存されたタブから送信できないようにしてください。一時停止中のフォームは `403 form_paused` を返します。

この定義をフォームの **Fields** タブに貼り付けます。試してみてください。大文字や空白を含む招待コードはパターンに合わず、設定したメッセージで失敗します。

フォーム: Wedding RSVP

- **招待コード** (`party`, text, 必須)
- **連絡用メールアドレス** (`email`, email, 必須)
- **ゲスト 1 の名前** (`guest_1_name`, text, 必須)
- **ゲスト 1 の料理** (`guest_1_meal`, select, 必須)
- **ゲスト 2 の名前** (`guest_2_name`, text)
- **ゲスト 2 の料理** (`guest_2_meal`, select)
- **ゲスト 3 の名前** (`guest_3_name`, text)
- **ゲスト 3 の料理** (`guest_3_meal`, select)
- **ゲスト 4 の名前** (`guest_4_name`, text)
- **ゲスト 4 の料理** (`guest_4_meal`, select)
- **踊りたくなる曲** (`song`, text)
- **ほかにお知らせいただくことはありますか？** (`note`, textarea)

フィールドは招待状の順に並んでいるので、CSV では各ゲストの名前の後に料理が続きます。必須なのは最初のゲストだけです。

## 未回答の招待と、注文する料理

1. **Submissions** から出欠の回答を CSV でエクスポートし、ゲストリストのスプレッドシートの `Replies` というタブにインポートします。
2. 同じ招待から 2 回回答があった場合は、最新の行を残します。`created_at` で新しい順に並べ替え、`party` 列で重複を削除してください。
3. 未回答の招待を一覧にします。コードはゲストリストの A 列、`party` は Replies の E 列にある前提です:

`未回答`:

```text
=FILTER(A2:C, A2:A <> "", ISNA(MATCH(A2:A, Replies!E2:E, 0)))
```

次に、ケータリング業者のために料理ごとの数を数えます。名前が料理の値と一致することはないので、すべてのゲスト列にまたがる 1 つの範囲で数えられます:

`魚料理の皿数`:

```text
=COUNTIF(Replies!G2:N, "fish")
```

| 数 | 求め方 |
| --- | --- |
| 出席者数 | `beef`、`fish`、`vegetarian`、`child` の数を合計 |
| 欠席 | 同じ範囲で `not_coming` を `COUNTIF` |
| お子さま用の皿数 | `child` を `COUNTIF`。多くのケータリング業者は別料金にしている |
| 食事制限のメモ | `note` 列を読む。アレルギーはここに書かれている |

> 通知メールは各ゲストのメールアドレスを reply-to にして届くので、質問にはそのまま受信トレイから返信できます。Ikiform がメールを送るのはあなたとパートナーで、ゲストには送りません。

## 招待状を送る前に

- **Allowed domains** に結婚式サイトのドメインを設定し、テスト中はビルダーのステージング用ドメインも追加します。
- Ikiform は同じメールアドレスからの重複送信を統合も拒否もしません。24 時間以内のまったく同じ再送信は、スパムスコアを上げるだけです。重複はリストを管理する場所か、エクスポート時に取り除いてください。コードごとに最新の回答が正式な回答です。
- リンクを持っている人なら誰でも、コードや名前を変更できます。結婚式ならそれで問題ありません。誰を招待したかはスプレッドシートが決め、未回答リストで不審な点がわかります。
- 年配の親族はフォームをまったく使わないかもしれません。電話や紙での回答もスプレッドシートに記録して、数が漏れないようにしましょう。

## 招待状を送る前に確認する

1. スマートフォンで自分の招待リンクを開きます。名前が表示され、それぞれに料理の選択肢があります。
2. 1 人のゲストで `Can't come` を選んで送信し、サンクスページに移動することを確認します。
3. ダッシュボードで **Submissions** を開きます。送ったすべてのフィールドを含む新しい送信データがあります。
4. 通知の各受信者の受信トレイを確認します。それぞれにフィールド入りのメールが届き、フォームに `email` フィールドがあれば **Reply** で送信者に返信できます。
5. CSV をインポートし、未回答リストに自分のコードが表示されなくなったことを確認します。
6. テスト用のコピーで締め切りを昨日に設定し、フォームが非表示になることを確認します。

## ハマりどころ

| 問題 | 対処法 |
| --- | --- |
| `party: Use the link from your invitation` 付きの `422` | コードに大文字、空白、その他の文字が含まれています。スプレッドシートのコードを修正するか、ゲストに自分のリンクを使ってもらってください。 |
| 名前の代わりに空の行が 1 つだけ表示される | リンクから `names` の部分が失われています。メッセージアプリがリンクを短縮したときによく起こります。完全なリンクか QR コードを送ってください。 |
| `422 validation_failed` | 送信がフォームのフィールド定義に合っていません。`error.fields` に各フィールドと理由が示されます。入力欄の `name` をフィールド ID に合わせてください。 |
| `403 origin_not_allowed` が返る、またはすべての送信がスパムになる | ページのドメインがフォームの **Allowed domains** にありません。ドメインと、ローカルテスト用の `localhost` を追加してください。登録したドメインのサブドメインは許可されます。 |
| ブラウザーが自分のページではなく Ikiform のサンクスページに移動する | `_redirect` は、ドメインが **Allowed domains** にあり、`https:` の URL でないと無視されます。ドメインを追加するか、代わりにフォーム設定で **Redirect after submit** を設定してください。 |

## よくある質問

### ゲストは他に誰が来るか見られますか？

いいえ。出欠の回答は Ikiform のダッシュボードとあなたの受信トレイに届きます。サイトに公開されるものは何もありません。

### フォームからゲストに確認メールを送れますか？

Ikiform からは送れません。Ikiform がメールを送るのはあなただけです。サンクスページに詳細を表示するか、各回答を Webhook でメールツールに送り、そこから確認メールを送ってください。

### 締め切り後に出欠の受け付けを止めるには？

サンプルのように日付を過ぎたらページ上のフォームを非表示にし、Ikiform で Pause form を選びます。一時停止中のフォームは新しい送信を 403 form_paused で拒否します。

### ゲストが 2 回回答したら？

両方の回答が保存されます。集計するときは、新しい順に並べ替えてコードで重複を削除し、招待コードごとに最新の回答を残してください。

### Ikiform は無料ですか？

いいえ、無料プランはありません。テストは無料で、支払う前に localhost から月 50 件のテスト送信ができます。本番運用するには、月 $6 で 500 件からの Pro か、1 回払いで 10,000 件 $49 または 50,000 件 $149 のパックを選べます。クレジットに有効期限はありません。

## その他のガイド

- [イベント登録](https://ikiform.com/ja/guides/event-registration.md): 自分のイベントページで出欠を受け付けます。フォーム、同伴者の上限、正確な人数集計、満員時の締め切り、受付リストまで、チケットアプリなしで。
- [Eventbrite なしで](https://ikiform.com/ja/guides/event-registration/without-eventbrite.md): 無料のコミュニティイベントの参加登録を自分のサイトで運営します。セッションの選択、自分のツールからの確認メール、部屋ごとの人数、受付リストまで。
- [ボランティア募集](https://ikiform.com/ja/guides/event-registration/volunteer-signup.md): シフトを選べるボランティア募集フォーム。当日の電話番号を集め、人手が足りないシフトを示してシフト表を作るスクリプト付き。
