ガイド

ガイド4 分で読めます

Mailchimp の埋め込みを使わないニュースレター登録フォーム

自分のマークアップでニュースレター登録フォームを作り、同意を記録し、ボットの登録を防ぎ、購読者を Kit、MailerLite、beehiiv など任意のツールに渡します。

Preet SutharIkiform 創業者

メール配信サービスの埋め込みコードを貼る代わりに、登録フォームを自分の HTML で書き、フォームバックエンドに向けます。バックエンドがアドレスと同意のチェックボックスを検証し、ボットを除外して署名付きの Webhook を送り、小さなリレーがメールツールの API で購読者を追加します。確認メール、ニュースレター、配信停止リンクはメールツールが送るので、あとでツールを変えるときも、変えるのはリレーだけで、すべてのフォームではありません。

どのメールツールにも埋め込みがあります。ページに貼り付ける、生成されたマークアップのかたまりです。動きはしますが、フォームはそのツールのものになります。送信先はそのプロバイダーで、プロバイダーのマークアップや、しばしばスタイルやスクリプトも一緒に入り、別のツールに移る日にはサイト中のコピーを探し回ることになります。このガイドでは、すでに使っているマークアップとフレームワークで自分のものと言える登録フォームを作り、ニュースレターを送るツールにつなぎます。

登録の流れ

ここには 2 つの仕事があり、それぞれ置き場所が違います。登録を集めるのはフォームの仕事です。アドレスを検証し、同意のチェックを確認し、ボットを防ぎ、いつ登録されたかを記録します。ニュースレターを送るのはメールの仕事です。アドレスを確認し、各号を送り、配信停止とバウンスを処理します。前者は Ikiform が、後者はメールツールが担います。両者を署名付きの Webhook がつなぎます。

ニュースレター登録がページからメールツールに届くまで登録フォームフッター、サイドバー、記事Ikiform同意とスパムをチェックダッシュボードすべての登録と同意通知メールあなたへ、任意署名付きWebhooksubmission.createdメールツール確認、配信、配信停止送信リレーニュースレター登録がページからメールツールに届くまで登録フォームフッター、サイドバー、記事Ikiform同意とスパムをチェックダッシュボードすべての登録と同意通知メールあなたへ、任意署名付き Webhooksubmission.createdメールツール確認、配信、配信停止送信リレー
  1. 読者がページの登録フォームに入力すると、Ikiform のエンドポイントに送信されます。
  2. Ikiform はアドレス、必須の同意チェックボックス、ハニーポット、スパムスコア、レート制限をチェックします。
  3. 受け付けた登録は、タイムスタンプ、origin、リファラーとともにダッシュボードに保存されます。
  4. Ikiform は登録ごとにあなたにメールで知らせることができます。読者にメールを送ることはありません。
  5. Ikiform が署名付きの submission.created Webhook を送ります。
  6. リレーが署名を検証して読者をメールツールに追加し、メールツールが確認メールを、のちには毎号を送ります。
どのメールツールを使っているかを知っているのはリレーだけです。ツールを変えても、フォーム、スパム除外、保存された記録は変わりません。

ニュースレター登録を集める 4 つの方法

方法得意なことトレードオフ
Mailchimp、Kit、MailerLite、beehiiv などメールツールの埋め込み運用するものがありません。確認、タグ付け、ウェルカムメールはツール自身の設定でつながっています。マークアップと挙動はツールのものです。Mailchimp によると埋め込みフォームはサイトのスタイルを継承するので、ページ上で見た目が変わることがあり、既存のフォームで reCAPTCHA をオンにするには新しいコードを生成して貼り直す必要があります。どのコピーも 1 つのプロバイダーに縛られます。
ツールの API を呼ぶ自前のサーバールートフォームとリクエストを完全に制御でき、API キーはサーバーに置いたままにできます。検証、ボット除外、レート制限、同意の記録を自分で作る必要があり、サイトが静的でもサーバーが要ります。
Typeform と Zapier のような、ホスト型フォームビルダーと自動化の組み合わせコード不要で、自動化ツールはあらゆるメール配信サービスに対応しています。ページになじまない iframe と、2 つのサブスクリプション。Webhook やブランディングはプランしだいです。
Ikiform のようなフォームバックエンドとリレーどのサイトでも自分のマークアップを使え、スパム除外、保存された同意の記録、署名付き Webhook があり、フォーム用のサーバーは不要です。Ikiform は読者にメールを送りません。確認メールと毎号のニュースレターは、小さなリレーか自動化を通してメールツールから送られます。

サイトが 1 つ、ツールが 1 つで、その埋め込みに満足していますか? それならそのままで構いません。フォームをデザインに合わせる必要があるとき、複数のサイトにまたがるとき、ツールより長く使うかもしれないときは、自分で作りましょう。

フォーム

良いニュースレターフォームは小さなものです。メールアドレス、挨拶に使う任意の名前、そしてラベルがそのまま約束になる同意のチェックボックスです。hidden の source 入力欄で、サイトのどこで登録されたかを記録します。スタックを選んでください。選択はこのガイドのすべてのコードサンプルに引き継がれます。

フォームをフッター、サイドバー、記事の末尾に貼り付けます。普通の方法で送信して自分のサンクスページに移動するので、JavaScript なしでも動きます。

footer.html
<form id="newsletter" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label for="nl-email">Email</label>
  <input id="nl-email" name="email" type="email" required autocomplete="email" placeholder="you@example.com" />

  <label for="nl-name">First name (optional)</label>
  <input id="nl-name" name="first_name" type="text" maxlength="80" autocomplete="given-name" />

  <label>
    <input name="consent" type="checkbox" value="true" required />
    Email me the newsletter. I can unsubscribe at any time.
  </label>

  <input type="hidden" name="source" value="footer" />
  <input type="hidden" name="_redirect" value="https://example.com/subscribed" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />

  <button>Subscribe</button>
  <p id="nl-status" role="status" hidden></p>
</form>

読者を記事にとどめるには、フォームの後ろにこのスクリプトを追加します。fetch で送信し、フォームを受信箱の確認を促す一文に置き換え、メールアドレスやチェックボックスについてはサーバーのメッセージを表示します。

newsletter.js
const form = document.querySelector("#newsletter");
const status = document.querySelector("#nl-status");
const button = form.querySelector("button");

form.addEventListener("submit", async (event) => {
  event.preventDefault();
  const body = new FormData(form);
  button.disabled = true;
  status.hidden = false;
  status.textContent = "Subscribing";
  try {
    const response = await fetch(form.action, { method: "POST", headers: { Accept: "application/json" }, body });
    const result = await response.json();
    if (result.ok) {
      form.replaceChildren(status);
      status.textContent = "Almost done. Open the email we sent you and confirm your address.";
      return;
    }
    const fields = result.error.fields ?? {};
    status.textContent = fields.email?.[0] ?? fields.consent?.[0] ?? result.error.message;
  } catch {
    status.textContent = "Couldn't reach the server. Try again.";
  }
  button.disabled = false;
});
  • frm_xxxxxxxxxxxxxxxx をダッシュボードにある自分のフォームの ID に置き換えます。
  • メール入力欄の name は email のままにしてください。Ikiform はこれを検証し、ドメインを小文字にして、使い捨てメールのドメインかどうかをチェックします。
  • hidden の _gotcha 入力欄がハニーポットです。人には見えず、すべての入力欄を埋めるボットは自らスパムだと名乗ることになります。
  • チェックボックスはチェックすると true を送ります。チェックしなければ何も送らず、必須のチェックボックスは This box must be checked で拒否されます。
  • メールツールが確認メールを送るので、成功の一文では受信箱を確認するよう伝えます。ダブルオプトインをオフにしているなら、普通のお礼に変えてください。
  • サーバー側の版はブラウザーの Origin ヘッダーを引き継ぎます。Ikiform は無料の localhost テストをこれで判別しますが、サーバー自身の fetch は何も送らないからです。
サーバー側の版はシークレットキー付きで送信するので、Ikiform は Allowed domains と人間確認をスキップします。その場合はすべての送信がサーバーの IP から来るため、訪問者ごとに 1 分あたり 5 件という Standard の制限が、全訪問者をまとめて数えることになります。サーバー経由で送信するフォームには Relaxed か Custom のレート制限を選び、IKIFORM_SECRET_KEY はサーバー専用の環境変数に置いてください。

フレームワークの設定はドキュメントにあります:Next.js、Astro、SvelteKit、Nuxt、React、Vue、プレーンな HTML。ニュースレターフォームのテンプレートは、同じフィールドを HTML、React、Next.js のサーバーアクションとして生成します。

フィールドと定義

下の定義をフォームの Fields タブに貼り付けると、ページが何を送ってきても Ikiform がサーバー側でそれを適用します。プレビューは同じバリデーターをブラウザーで実行します。チェックを入れずに送信すると、ボットや壊れたページが受け取るエラーを確認できます。

プレビュー

Ikiform のバリデーターをブラウザーで実行します。何も送信されません。

実際のページでは source は hidden 入力欄です。ここでは試せるように表示されるテキストフィールドにしています。
フィールド理由注意点
email購読者必須。type="email" でスマートフォンに適切なキーボードが出る
first_name各号の挨拶任意。ほとんどのメールツールに対応づけられる名前フィールドがあります
consent本人がメールを希望したという記録必須のチェックボックス。true として保存
sourceサイトのどのフォームで登録されたか:フッター、記事、ポップアップhidden。設置場所ごとに別の値を設定し、タグやフィールドとして渡します

フィールドを定義すると、Ikiform は知らない入力を unknown_field で拒否するので、ページに入力欄を追加する前に定義にフィールドを追加してください。_redirect のように _ で始まる名前は Ikiform への指示で、フィールドには数えられません。

ニュースレターは本人が希望したメールです。チェックボックスでその希望を明示し、保存された送信データがそれを記録します。受け付けた登録ごとに Ikiform が保持するのは次の内容です。

data.fields
{
  "email": "ada@example.com",
  "first_name": "Ada",
  "consent": true,
  "source": "footer"
}

フィールドのほかに、各送信データには created_at のタイムスタンプ、ページの origin とリファラー、国、ブラウザーのユーザーエージェントがあります。これらを合わせると、いつどこでチェックが入れられたかがわかります。この記録をあとで役立てるための習慣が 2 つあります。

  1. ラベルは約束として書きます。 「ニュースレターをメールで受け取ります。いつでも配信を停止できます。」なら、何が届くかが伝わります。お知らせやオファーも送るなら、ラベルにそう書いてください。
  2. 文言を変えたら日付を記録します。 保存された true は本人が同意したことを示しますが、どの文言にかは示しません。ラベルの変更履歴を日付付きで短く残しておけば、どの登録も、そのとき見た文言と照合できます。

Ikiform は記録を保持しますが、あなたや読者が住む地域のルールが何を求めるかは教えられません。詳しい人に確認してください。

確認メールはメールツールから送る

Ikiform はフォームに入力した本人にメールを送りません。通知メールはあなたとチームだけに届くので、自動返信、確認メール、ダブルオプトインはありません。それらは Webhook をきっかけにメールツールから送ってください。この分担は意図的なものです。ニュースレターを送るツールは、誰が確認し、誰が配信停止し、どのアドレスがバウンスしたかをすでに把握しています。別のシステムが確認メールを送ると、それらの記録がずれていきます。

そのためリレーは、メールツールが独自の確認メールを送る状態で読者を追加し、読者がクリックするとツールがその人を有効にします。これを有効にする方法はツールごとに違い、フォームの設定、アカウントのトグル、API リクエストのフラグのいずれかです。ダブルオプトインのガイドでは 3 つすべてと、既存の購読者がもう一度登録したときの動作を扱っています。

リレー

リレーは、Ikiform の Webhook を受け取り、署名をチェックしてメールツールの API を呼ぶ短い関数です。公開された HTTPS の URL と、両側に 1 つずつのシークレットが必要です。これは Next.js のルートハンドラーですが、同じコードは fetch がある任意のランタイムで動きます。

app/api/newsletter/route.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { addSubscriber } from "@/lib/email-tool";

export async function POST(request: Request) {
  const payload = await request.text();
  let event;
  try {
    event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.IKIFORM_WEBHOOK_SECRET! });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
  if (event.type !== "submission.created") return new Response(null, { status: 204 });

  const fields = event.data.fields;
  if (fields.consent !== true) return new Response("No consent, skipped", { status: 200 });

  const answer = await addSubscriber({
    email: String(fields.email),
    firstName: typeof fields.first_name === "string" ? fields.first_name : undefined,
    source: typeof fields.source === "string" ? fields.source : "unknown",
    referrer: typeof event.data.meta.referrer === "string" ? event.data.meta.referrer : undefined,
  });
  if (answer.status === 429) {
    return new Response("Email tool rate limit", {
      status: 503,
      headers: { "retry-after": answer.headers.get("retry-after") ?? "60" },
    });
  }
  if (!answer.ok) return new Response(`Email tool answered ${answer.status}`, { status: 502 });
  return new Response(null, { status: 204 });
}
  • verifyWebhook は HMAC 署名とタイムスタンプをチェックします。これがないと、URL を見つけた誰でもリストにアドレスを追加できます。
  • ダッシュボードの Send test による endpoint.test イベントには 204 を返し、処理を飛ばします。
  • 同意のチェックは、フォームの定義の後ろにある 2 つ目の鍵です。
  • ツールに依存するのは addSubscriber だけです。ツールごとの中身は Kit、MailerLite、beehiiv の各ページにあります。

リレーの応答によって、Ikiform の次の動作が決まります。

メールツールの各応答に対してリレーが Ikiform に返すもの200 か 201追加または更新204内容なし完了配信成功429レート制限503Retry-After 付き待機その後リトライ4xx か 5xx拒否またはダウン502ツールのステータス付きリトライ同じ webhook-idメールツールの応答リレーの応答Ikiformメールツールの各応答に対してリレーが Ikiform に返すもの200 か201追加または更新204内容なし完了配信成功429レート制限503Retry-After付き待機その後リトライ4xx か5xx拒否またはダウン502ツールのステータス付きリトライ同じwebhook-idメールツールの応答リレーの応答Ikiform
  1. メールツールが購読者を追加または更新した場合:リレーは 204 を返し、配信は succeeded になります。
  2. メールツールがレート制限中の場合:リレーは Retry-After 付きで 503 を返し、Ikiform はその時間だけ待ってから次を試みます。
  3. メールツールがリクエストを拒否したかダウンしている場合:リレーは 502 を返し、Ikiform は同じ webhook-id でスケジュールどおりにリトライします。
すべての試行はリレーの応答とともにエンドポイントの配信ログに残るので、ツールのステータスを含む 502 を見れば、何を直すべきかがわかります。

ダッシュボードの Webhooks にリレーの URL を追加し、ニュースレターのフォームを選んで、whsec_ のシークレットを IKIFORM_WEBHOOK_SECRET にコピーします。ワークスペースには最大 3 つのエンドポイントを置けます。URL はポート 443 の公開 HTTPS である必要があり、workers.dev と pages.dev のホスト名は拒否されるので、Worker にはカスタムドメインを設定してください。リトライ、ペイロード、署名の方式は Webhook のドキュメントに、各配信を 1 回だけ保存する版はフォームの送信データを自分のサーバーへにあります。

コードを書きたくないですか? リレーの代わりに Webhook を自動化ツールに向け、そのツールのメールツール用アクションを使ってください。Zapier、Make、n8n を参照してください。ワンクリックの連携はありません。どのツールにも、直接、または Zapier や n8n などの自動化ツールを通して、署名付きの Webhook で接続します。

ボットとリスト爆撃を防ぐ

ボットによる登録は、ほとんどのフォーム以上にニュースレターを傷つけます。ボットが登録した実在のアドレスには頼んでもいないメールが届き、その人たちからの苦情は送信元ドメインの評判を下げます。被害者のアドレスを何百ものフォームに一斉に登録して受信箱を埋め尽くすボットもいて、確認メールを送るフォームはすべてその片棒を担ぐことになります。

防御防げるもの設定
ハニーポットすべての入力欄を埋めるボット非表示の _gotcha 入力欄
必須の同意メールアドレスだけを送るスクリプト定義で required: true にした consent チェックボックス
スパムスコア使い捨てアドレス(+2)、同一内容の繰り返し(+3)、リンク、スパムフレーズ。5 に達した登録はスパムとして保存されますなし
レート制限ループで送信を繰り返す 1 人の訪問者デフォルトでオン: Standard、訪問者ごとに 1 分あたり 5 件
人間確認本物のブラウザーを動かすボットSpam check を Ikiform に設定すると、キーの管理なしで Cloudflare Turnstile が動きます
許可ドメインほかのサイトにコピーされたフォームのエンドポイントフォームを置くすべてのドメインを登録します

スパムにも本物の登録と同じ成功の応答が返り、Webhook は送られません。そのためメールツールには届かず、確認メールが送られることもありません。本物の読者がスパムに入ってしまったら、スパムではないとマークすれば、その時点で Webhook が送られます。各チェックとそのスコアはスパム対策のドキュメントで説明しています。

人は 1 回しか購読しないので、ニュースレターのフォームには訪問者ごとの厳しい制限が合っています。読者が 1 つの IP を共有するオフィスやキャンパスから読んでいるなら、Standard ではまとめて数えられます。その場合は訪問者ごとに 1 分あたり 20 件の Relaxed が安全です。レート制限を参照してください。

1 つのフォームを多くのページに

1 つのエンドポイントを、全ページのフッター、各記事の末尾、/newsletter ページに置けます。どの設置場所が登録につながっているかを知るため、場所ごとに別の source の値を付けてください:

  • footer: 全ページで表示されます。メールアドレスとチェックボックスだけにしましょう。
  • post: 記事を読み終えた読者で、多くの場合もっとも登録につながります。
  • newsletter-page: SNS のプロフィールからのリンク先です。サンプル号を載せる余裕があります。

すべての送信データにはリファラー、つまり読者がいたページそのものも記録されるので、source で設置場所が、リファラーで記事がわかります。フォームを表示する各ドメインを Allowed domains に追加してください。フォームごとに 20 件までで、登録したドメインのサブドメインは自動的に許可されます。

同じ読者が 2 回

Ikiform はメールアドレスで重複する送信をまとめたり拒否したりしません。24 時間以内の同一内容の繰り返しはスパムスコアを上げるだけです。重複はリストの置き場所かエクスポート時に除去してください。ニュースレターではほとんど問題になりません。Kit、MailerLite、beehiiv はいずれもメールアドレスをキーに購読者を管理するので、繰り返しは 2 人目を作らず 1 つの連絡先を更新します。

あとでメールツールを変える

フォームを自分で持つことが報われるのはここです。メールツールを乗り換えるには、通常サイト上のすべての埋め込みを置き換える必要があります。ここではフォームは背後にどのツールがあるかを知りません:

別のメールツールに乗り換えると何が変わるか埋め込みの場合自分のフォームの場合全ページ貼り付けた埋め込みコード古いツールフォームの送信先新しいツール全ページに新しい埋め込み全ページ変更なしIkiform変更なしリレー関数 1 つだけ変更送信すべて置き換え送信Webhook別のメールツールに乗り換えると何が変わるか埋め込みの場合自分のフォームの場合全ページ貼り付けた埋め込みコード古いツールフォームの送信先新しいツール全ページに新しい埋め込み全ページ変更なしIkiform変更なしリレー関数 1 つだけ変更送信すべて置き換え送信Webhook
  1. 埋め込みでは、すべてのページに古いツールへ直接送信するコードがあるので、乗り換えるにはそのすべてを置き換えることになります。
  2. 自分のフォームなら、すべてのページは Ikiform に送信し続け、Ikiform は同じ Webhook を送り続けます。
  3. 変わるのは中継の addSubscriber 関数だけで、新しいツールの API を呼ぶようにします。
必要なら 1 週間両方のツールを動かしてください。Webhook のエンドポイント 2 つ、中継 2 つ、フォーム 1 つです。そのあと古いエンドポイントを削除します。

既存の購読者は、古いツール自身のエクスポートで移してください。誰が確認済みで誰が解除したかを知っているのはそのツールだけです。Ikiform の CSV エクスポートは 1 ファイル 100,000 行までで、数を確認するためのもので、インポート用ではありません。

状況に合わせて選ぶ

上のフォームはどこでも同じです。これらのページでは、確認メール、サーバーのないサイト、3 つのメールツールの具体的な API 呼び出しを扱います。

動作を確認する

フォームを全ページに追加する前に、これを一通り確認してください。Ikiform に無料プランはありません。テストは無料です。プランのないワークスペースでも、localhost からのテスト送信を月 50 件まで受け付けます。本番運用するには、500 件で月 $6 からの Pro を選ぶか、買い切りにしてください。10,000 件で $49、または 50,000 件で $149 で、クレジットに有効期限はありません。料金を参照してください。

  1. フォームの Allowed domains に自分のサイトのドメインを追加し、開発中は localhost も追加します。空のままにすると、どこからの送信も受け付けます。
  2. ブラウザーの開発者ツールでチェックボックスを外したまま送信するか、一時的に required を削除します。This box must be checked 付きの 422 が返り、何も保存されません。
  3. 自分のアドレスで正しく送信します。受信箱を確認するよう促す一文が表示されるか、サンクスページに移動します。
  4. ダッシュボードで Submissions を開きます。送ったすべてのフィールドを含む新しい送信データがあります。
  5. Webhooks でエンドポイントを開きます。配信は succeeded と表示され、中継の応答が見えます。
  6. メールツールを開きます。購読者が登録されており、ダブルオプトインがオンなら未確認の状態で、確認メールが受信箱に届いています。
  7. ハニーポットを埋めて _gotcha=bot で送信します。成功の応答は返りますが、送信データはスパムとして保存され、メールも Webhook も送られません。
  8. 何も届かない場合は、ダッシュボードのステータスフィルターを Spam に切り替えてください。スパムにも本物の送信と同じ成功の応答が返ります。

トラブルシューティング

問題対処法
consent の 422 validation_failedチェックボックスにチェックが入っていないか、入力欄の name が consent ではありません。サーバー側の実装では true、"true"、"on" のいずれかを送る必要があります。チェックのないボックスは何も送りません。
unknown_field の 422 validation_failed定義にない入力欄をページが送っています。あとから追加した hidden の source やトラッキング用の入力欄がよくある原因です。定義に追加するか、入力欄を削除してください。
403 origin_not_allowed が返る、またはすべての送信がスパムになるページのドメインがフォームの Allowed domains にありません。ドメインと、ローカルテスト用の localhost を追加してください。登録したドメインのサブドメインは許可されます。
429 rate_limited1 人の訪問者がフォームのレート制限を超えて送信しました。Standard では訪問者ごとに 1 分あたり 5 件までです。Retry-After まで待つか、共有の IP 1 つから送信するフォームには Relaxed か Custom を選んでください。
送信データはダッシュボードにあるのに、メールも Webhook も届かないスパムとして保存されています。スパムでは何も送られません。Spam フィルターで開いて理由を確認し、スパムではないとマークすると、メールと Webhook が送られます。
登録は Ikiform に届くのに、メールツールには届かないWebhooks で配信ログを確認します。400 は中継のシークレットが間違っているという意味です。502 にはメールツールのステータスが入っており、たいていは API キー、リスト ID、フォーム ID の誤りです。
購読者はメールツールにいるが、確認メールが届かないツールでダブルオプトインがオフになっているか、中継が購読者を確認済みとして作成しています。各ツールの設定はダブルオプトインを参照してください。
ブラウザーが自分のページではなく Ikiform のサンクスページに移動する_redirect は、ドメインが Allowed domains にあり、https: の URL でないと無視されます。ドメインを追加するか、代わりにフォーム設定で Redirect after submit を設定してください。

よくある質問

手順で詰まったときや、あなたの状況に合うガイドがほしいときはメールでどうぞ: hello@ikiform.com