lobsite! ログイン アカウント作成

ドキュメント /

フォーム

Lobsite サイトのどの HTML フォームでもメッセージを集められます。action を /_lobsite/forms/<name> に向けてデプロイしてください。書くバックエンドも、追加するスクリプトも、貼り付けるキーもありません。送信内容はダッシュボードの送信内容ページとメールに届きます。

<form action="/_lobsite/forms/contact" method="POST">
  <input name="email" type="email" required>
  <textarea name="message" required></textarea>
  <button>Send</button>
</form>

フォームの仕組み

  • action がフォームの名前を決めます。 /_lobsite/forms/contact はフォーム contact です。名前には小文字、数字、-、_ を使います。目的ごとに 1 つの名前を使い(contact、newsletter、quote)、複数のページで 1 つのフォームを共有できます。
  • フォームはデプロイ時に検出されます。 デプロイが HTML ファイルを読み取り、/_lobsite/forms/ に送信する各フォームを記録します。フォームはデプロイするフォルダの HTML ファイルになければなりません。JavaScript のレンダリング後にのみ存在するフォームは検出されません(フレームワーク参照)。
  • 項目は名前のとおりに保存されます。 name のある項目はすべてテキストとして保持されます。email という項目は、通知メールの Reply-To と送信内容ページのタイトルに使われます。ファイルのアップロードには対応していません。
  • スパム対策は自動で追加されます。 ページの配信時に、隠しハニーポット項目と署名付きタイムスタンプがフォームに追加されます。ハニーポットに入力された送信や 2 秒以内に戻ってきた送信はスパムとして分けられ、1 人の訪問者からの連続した大量の送信は拒否されます。
  • 送信後、訪問者には戻るリンク付きのサンクスページ、または redirect で設定したページが表示されます。
  • フォームは本番 URL で機能します。 プレビューデプロイは送信を受け付けず、アカウントなしでデプロイしたサイトは取得後に受け付けます。

フォームの種類

各フォームは お問い合わせ フォームか ウェイトリスト です。種類によって送信内容ページでの表示が決まります。お問い合わせフォームの行にはメッセージが、ウェイトリストの行には参加者と参加元ページが表示され、ウェイトリストは表の上に数が表示されます。どちらも同じ通知メールを送信します。

Lobsite はデプロイ時に種類を選びます。

  • 訪問者がメールアドレスと、最大で名前のみを入力するフォームは ウェイトリスト です。隠し項目、_ で始まる項目、チェックボックス(同意ボックス)は数えません。
  • waitlist、newsletter、signup、subscribe、early-access、beta、notify という名前のフォームも、項目にかかわらずウェイトリストです。
  • それ以外のフォームはすべて お問い合わせ フォームです。

自分で選ぶには、lobsite.toml で type を設定します。

[forms.launch]
type = "waitlist"   # or "contact"

ウェイトリストの登録内容はフォームがある限り保持され、その他の送信内容はプランの保持期間に従います(制限参照)。

お問い合わせフォーム

名前、メールアドレス、メッセージを含む完全なページです。ラベルと autocomplete の値で入力しやすくなり、required 属性で空の送信を送信前に止めます。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Contact</title>
</head>
<body>
  <h1>Get in touch</h1>
  <form action="/_lobsite/forms/contact" method="POST">
    <label>Name
      <input name="name" autocomplete="name" required>
    </label>
    <label>Email
      <input name="email" type="email" autocomplete="email" required>
    </label>
    <label>Message
      <textarea name="message" rows="5" required></textarea>
    </label>
    <button type="submit">Send</button>
  </form>
</body>
</html>

同じ項目をサーバーでも確認し、訪問者を独自のサンクスページに移動させるには、lobsite.toml にフォームを追加して thanks.html を作成してください。

[forms.contact]
required = ["name", "email", "message"]
types    = { email = "email" }
redirect = "/thanks"

ウェイトリスト

公開前に必要なのはメールアドレス欄だけです。フォームの名前でウェイトリストになり、type を設定すると明示できます。登録内容は送信内容ページで数えられ、フォームがある限り保持されます。

<form action="/_lobsite/forms/waitlist" method="POST">
  <label for="wl-email">Get early access</label>
  <input id="wl-email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required>
  <button>Join the waitlist</button>
</form>
[forms.waitlist]
type     = "waitlist"
required = ["email"]
types    = { email = "email" }

ニュースレター登録

項目は 1 つで十分です。同じサイトの 2 つ目のフォームには独自の名前を付けるので、登録とメッセージは送信内容ページとエクスポートで分かれます。メールアドレス欄のみ(最大で名前も)のフォームはウェイトリストです。フォームの種類をご覧ください。

<form action="/_lobsite/forms/newsletter" method="POST">
  <label for="nl-email">Get updates by email</label>
  <input id="nl-email" name="email" type="email" autocomplete="email" required>
  <input type="hidden" name="_redirect" value="/subscribed">
  <button>Subscribe</button>
</form>

_redirect は、送信後に表示するページを選ぶ隠し項目です。同じサイトのパスまたは URL にする必要があり、lobsite.toml の redirect が優先されます。

見積もり依頼

セレクト、ラジオボタン、チェックボックスは通常どおり機能します。同じ名前のチェックボックスはカンマ区切りの 1 つの値として保存されます。

<form action="/_lobsite/forms/quote" method="POST">
  <input name="name" autocomplete="name" required>
  <input name="email" type="email" autocomplete="email" required>
  <input name="phone" type="tel" autocomplete="tel">
  <select name="budget">
    <option>Under $1,000</option>
    <option>$1,000 to $5,000</option>
    <option>Over $5,000</option>
  </select>
  <fieldset>
    <legend>Services</legend>
    <label><input type="checkbox" name="services" value="Design"> Design</label>
    <label><input type="checkbox" name="services" value="Development"> Development</label>
    <label><input type="checkbox" name="services" value="Hosting"> Hosting</label>
  </fieldset>
  <textarea name="details" required></textarea>
  <button>Request a quote</button>
</form>

ページを離れずに送信

新しいページを読み込まずにその場でメッセージを表示するには、fetch でフォームを送信します。隠しスパム項目も送られるよう new FormData(form) で本文を作成し、Accept ヘッダーで JSON を要求してください。

<form id="contact" action="/_lobsite/forms/contact" method="POST">
  <input name="email" type="email" required>
  <textarea name="message" required></textarea>
  <button>Send</button>
  <p id="contact-status" role="status"></p>
</form>
<script>
  const form = document.getElementById("contact");
  const status = document.getElementById("contact-status");
  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    status.textContent = "Sending…";
    const res = await fetch(form.action, {
      method: "POST",
      body: new FormData(form),
      headers: { Accept: "application/json" },
    });
    const answer = await res.json();
    if (answer.ok) {
      form.reset();
      status.textContent = "Thanks! We'll be in touch.";
    } else {
      status.textContent = answer.errors ? Object.entries(answer.errors).map(([field, why]) => `${field}: ${why}`).join(", ") : "Something went wrong. Please try again.";
    }
  });
</script>

応答は {"ok": true}、通過しなかった項目の場合は {"ok": false, "errors": {"email": "Required"}}、または {"ok": false, "error": "rate_limited"}(他に too_large、not_found、forms_off)です。スクリプトがなくても、同じフォームは通常のフォームとして機能します。

フレームワーク

React、Vue、Svelte、Astro などは、フォームがビルドされた HTML にある場合に機能します。これはプリレンダリングと静的エクスポートが生成するものです(Astro と Eleventy はデフォルトで、output: "export" の Next.js、prerender の SvelteKit、nuxt generate の Nuxt)。action と method 属性は <form> 要素自体に残してください。

シングルページアプリでは、フォームはビルドされた HTML にあり、配信されたままである必要があります。JavaScript にのみ存在するフォームは記録されず送信が拒否され、ブラウザが再レンダリングするフォームはスパム項目を失うため、メッセージがスパムに入ります。

// React: a plain form element, prerendered into the HTML.
export function Contact() {
  return (
    <form action="/_lobsite/forms/contact" method="POST">
      <input name="email" type="email" required />
      <textarea name="message" required />
      <button>Send</button>
    </form>
  );
}

設定

各フォームは lobsite.toml にセクションを持てます。すべてのキーは任意で、設定はデプロイと一緒に反映されます。

[forms.contact]
type      = "contact"                            # contact or waitlist; inferred when left out
required  = ["email", "message"]                 # fields that can't be empty
types     = { email = "email", phone = "tel" }   # text, email, number, url or tel
redirect  = "/thanks"                            # the page shown after sending
notify    = ["you@example.com"]                  # who gets an email for each message
webhook   = "https://example.com/hooks/contact"  # POSTs each submission as JSON

required や types に失敗した送信は保存されず、訪問者には修正すべき点と戻るリンクが表示されます。無料プランでは、notify はアカウントのメールアドレスのみで、webhook は利用できません。

送信内容を読む

  • ダッシュボードの送信内容ページに、すべてのフォームの送信内容が 1 つの表で表示されます。検索、サイトとフォームの種類での絞り込み、チェックで検出されたものを見るスパムへの切り替えができます。送信内容は開くまで新着です。
  • 各メッセージはアカウントのアドレスにメールで届き、Reply-To は送信者に設定されます。
  • lobsite forms ls はフォームを一覧表示し、lobsite forms export contact --csv は 1 つのフォームの送信内容をダウンロードします。送信内容ページの CSV エクスポートは、表に表示されているものをダウンロードします。

無料プランのフォームは制限モードで動作します。サイトごとの月間上限、通知はアカウントのメールアドレスのみ、Webhook なしです。Standard プランでは、Webhook、任意の確認済み通知先アドレスが追加され、月間上限がなくなります。制限をご覧ください。