フォーム ID

Eleventy

Nunjucks、Liquid、Markdown のテンプレートで Ikiform のフォームを描画する Eleventy のショートコード。フォーム ID はグローバルデータで管理します。

Eleventy は静的な HTML を出力するので、フォームはクライアントの JavaScript なしで送信されます。ショートコードならマークアップを 1 か所にまとめられ、Nunjucks、Liquid、Markdown のどのファイルでも同じように動きます。

セットアップ

  1. ショートコードを追加する

    eleventy.config.js
    const escape = (value) => String(value).replace(/[&<>"']/g, (char) => `&#${char.charCodeAt(0)};`);
    
    export default function (eleventyConfig) {
      eleventyConfig.addShortcode("ikiform", (formId, thanks = "", subject = "") =>
        [
          `<form class="ikiform" action="https://ikiform.com/f/${encodeURIComponent(formId)}" method="post">`,
          '<label>Email <input name="email" type="email" autocomplete="email" required></label>',
          '<label>Message <textarea name="message" rows="5"></textarea></label>',
          thanks && `<input type="hidden" name="_redirect" value="${escape(thanks)}">`,
          subject && `<input type="hidden" name="_subject" value="${escape(subject)}">`,
          '<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>',
          '<button type="submit">Send</button>',
          "</form>",
        ]
          .filter(Boolean)
          .join("\n"),
      );
    }
    • 行は意図的に空行なしでつなげています。Markdown では空行で HTML ブロックが終わり、フォームの残りがテキストとして扱われてしまいます。
    • これは ES モジュールの構文を使っています。package.json に "type": "module" がない場合は、ファイル名を eleventy.config.mjs にしてください。
  2. フォーム ID をグローバルデータに置く

    _data/ikiform.js
    export default {
      formId: process.env.IKIFORM_FORM_ID ?? "frm_xxxxxxxxxxxxxxxx",
      thanks: "https://example.com/thanks/",
    };

    グローバルデータは、すべてのテンプレートで ikiform として使えます。Ikiform はそれ以外のリダイレクトを無視するため、サンクスページの URL は https: の絶対 URL にする必要があります。

  3. 使う

    contact.md
    ---
    title: Contact
    ---
    
    Questions about pricing? Write to us.
    
    {% ikiform ikiform.formId, ikiform.thanks, "Pricing question" %}

    Markdown ファイルはデフォルトで Liquid で処理されるので、タグはそのまま動きます。タグは独立した行に置き、4 つのスペースでインデントしないでください。インデントすると Markdown がコードブロックとして描画します。同じタグは .njk と .liquid のファイルでも動きます。

_redirect に従うのは、フォームの許可ドメインに自分のサイトが含まれている場合だけです。_redirect のルールを参照してください。

許可ドメイン

本番とそれぞれのプレビューのホストを登録します。Eleventy のサイトは Netlify や Cloudflare Pages にデプロイされることが多く、プレビューの扱いはそれぞれ異なります。

フォームが動く場所許可ドメインに追加するもの
npx @11ty/eleventy --servelocalhost。http://localhost:8080 に一致します。Ikiform が比較するのはホスト名だけで、ポートは比較しません。
自分のドメインexample.com(www.example.com も含まれます)
Netlifyyour-site.netlify.app。デプロイプレビュー(deploy-preview-12--your-site.netlify.app)やブランチデプロイ(branch--your-site.netlify.app)はそのサブドメインではないので、テストする間はプレビューの正確なホストを追加してください。
Cloudflare Pagesyour-project.pages.dev。abc123.your-project.pages.dev のようなプレビュー URL はそのサブドメインなので、すでに一致します。
  • netlify.app や pages.dev だけを追加しないでください。他の人のサイトも含め、そのホスト上のすべてのサイトが一致してしまいます。

テストのチェックリスト

  1. 開発サーバーを実行し、ページのソースを表示します。フォームは <pre><code> ブロックの中ではなく、プレーンな HTML になっているはずです。
  2. 許可ドメインに localhost を入れてローカルで送信し、送信データが Ikiform に表示されることを確認します。
  3. プレビューをデプロイし、プレビューのホストからもう一度送信します。
  4. 本番で送信し、サンクスページに移動することを確認します。

トラブルシューティング

症状原因対処
フォームがページにコードとして表示されるMarkdown ファイルでショートコードが 4 つのスペースでインデントされているタグを行の先頭に移動します。
フォームの半分が段落として描画されるショートコードの出力に空行が含まれていて、Markdown の HTML ブロックが終わってしまう上の設定のように、空行なしで行をつなげます。
Eleventy の起動時に SyntaxError: Unexpected token 'export' が出るCommonJS のプロジェクトで、設定ファイルが ES モジュールの構文を使っているファイル名を eleventy.config.mjs にするか、package.json に "type": "module" を追加します。
Nunjucks や Liquid が ikiform タグを見つけられないEleventy が設定ファイルを読み込んでいないファイルがプロジェクトのルートにあり、名前が eleventy.config.js か .mjs になっているか確認します。
送信データが origin_mismatch でスパムフィルターの下に届く送信したページが、フォームの許可ドメインに含まれていない上の表のホストを追加します。Reject を選んでいる場合、同じ送信には代わりに 403 origin_not_allowed が返ります。