このチュートリアルでは、Cloudflare Workers と Airtable ↗ を使い、フロントエンドのユーザーインターフェースからのフォーム送信を永続化します。Airtable は無料で使えるスプレッドシートで、開発者向けの扱いやすい API があります。Workers が受信したフォーム送信を処理し、Airtable の REST API ↗ で、あとから参照できるよう Airtable base(Airtable でのスプレッドシートの呼び方)に非同期でデータを保存します。
すべてのチュートリアルは、Cloudflare Workers アカウント、C3 ↗、および Wrangler のセットアップが完了している前提です。セットアップは Get started ガイド で行います。
このチュートリアルでは、お問い合わせフォームからの入力を処理する Workers 関数を作ります。参照するフォームでは、名、姓、メールアドレス、電話番号、件名、メッセージを集めます。
このチュートリアルで使うフォームの簡易例を確認します。<form> タグの action パラメーターは、このチュートリアルで作るデプロイ済み Workers アプリケーションを指すようにします。
<form action="https://workers-airtable-form.signalnerve.workers.dev/submit" method="POST">
<div>
<label for="first_name">First name</label>
<input type="text" name="first_name" id="first_name" autocomplete="given-name" placeholder="Ellen" required />
</div>
<div>
<label for="last_name">Last name</label>
<input type="text" name="last_name" id="last_name" autocomplete="family-name" placeholder="Ripley" required />
</div>
<div>
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" placeholder="[email protected]" required />
</div>
</div>
<div>
<label for="phone">
Phone
<span>Optional</span>
</label>
<input type="text" name="phone" id="phone" autocomplete="tel" placeholder="+1 (123) 456-7890" />
</div>
<div>
<label for="subject">Subject</label>
<input type="text" name="subject" id="subject" placeholder="Your example subject" required />
</div>
<div>
<label for="message">
Message
<span>Max 500 characters</span>
</label>
<textarea id="message" name="message" rows="4" placeholder="Tenetur quaerat expedita vero et illo. Tenetur explicabo dolor voluptatem eveniet. Commodi est beatae id voluptatum porro laudantium. Quam placeat accusamus vel officiis vel. Et perferendis dicta ut perspiciatis quos iste. Tempore autem molestias voluptates in sapiente enim doloremque." required></textarea>
</div>
<div>
<button type="submit">
Submit
</button>
</div>
</form>フォーム送信を処理するには、受信したフォームデータを解析し、Airtable への送信に備える Worker を作成してデプロイします。
新しい airtable-form-handler Worker プロジェクトを作成します。
npm create cloudflare@latest -- airtable-form-handleryarn create cloudflare airtable-form-handlerpnpm create cloudflare@latest airtable-form-handlerセットアップでは、次のオプションを選びます。
- What would you like to start with? では、
Hello World exampleを選びます。 - Which template would you like to use? では、
Worker onlyを選びます。 - Which language do you want to use? では、
JavaScriptを選びます。 - Do you want to use git for version control? では、
Yesを選びます。 - Do you want to deploy your application? では、
Noを選びます(デプロイ前にいくつか変更します)。
作成したディレクトリへ移動します。
cd airtable-form-handlerWorker が完成すると、Airtable の REST API 経由で Airtable base へデータを送ります。
Airtable アカウントがない場合は作成します(無料プランでこのチュートリアルは完了できます)。Airtable のダッシュボードで Start from scratch を選び、新しい base を作成します。
新しい base を作成したら、フロントエンドのフォームで使えるように設定します。既存の列を削除し、次のフィールドタイプで 6 つの列を作成します。
| フィールド名 | Airtable のフィールドタイプ |
|---|---|
| First Name | "Single line text" |
| Last Name | "Single line text" |
| "Email" | |
| Phone Number | "Phone number" |
| Subject | "Single line text" |
| Message | "Long text" |
フィールド名は大文字と小文字を区別します。フィールド名を変えた場合は、このチュートリアル後半で Airtable へ送る API リクエストでも、新しいフィールド名と完全に一致させる必要があります。テーブル名は任意で変更できます。デフォルトでは Table 1 のような名前です。以降のコードでは、Form Submissions のような分かりやすい名前に変更した前提で進めます。
次に、Airtable の API ページ ↗ を開き、新しい base を選びます。base の情報を見るには、Airtable へのログインが必要です。API ドキュメントのページで Airtable base ID を確認します。
Airtable base へアクセスするための Personal access token も作成します。Airtable の Personal access tokens ↗ ページを開き、新しいトークンを作成します。トークンは次のように設定します。
- Scope: トークンに
data.records:writeスコープを設定する - Access: このチュートリアルで使っている base へのアクセスを許可する
作成したアクセストークンを、アプリケーションに設定します。コードベースからトークンを使えるようにするには、wrangler secret コマンドを使います。secret コマンドは、環境変数を暗号化して関数で使えるように保存し、ユーザーには見せません。
wrangler secret put を実行し、シークレット名として AIRTABLE_ACCESS_TOKEN を渡します。
npx wrangler secret put AIRTABLE_ACCESS_TOKENEnter the secret text you would like assigned to the variable AIRTABLE_ACCESS_TOKEN on the script named airtable-form-handler:
******
🌀 Creating the secret for script name airtable-form-handler
✨ Success! Uploaded secret AIRTABLE_ACCESS_TOKEN.続ける前に、Airtable から用意しておくキーを確認します。
- Airtable Table Name: テーブル名です。Form Submissions など。
- Airtable Base ID: base の API ページ上部にある英数字の base ID です。
- Airtable Access Token: 新しい Airtable base の情報へアクセスするために、ユーザーが作成した Personal Access Token です。
Airtable base の設定と、API との通信に必要なキーと ID が揃ったら、フォームからのデータを Airtable へ永続化する Worker を設定します。
Worker プロジェクトの index.js ファイルで、デフォルトのコードを、リクエストに応答できる Workers の fetch ハンドラーに置き換えます。リクエストされた URL のパス名が /submit のときは新しいフォーム送信を処理し、それ以外は 404 Not Found レスポンスを返します。
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/submit") {
await submitHandler(request, env);
}
return new Response("Not found", { status: 404 });
},
};submitHandler には 2 つの役割があります。まず、HTML5 フォームから送られてくるフォームデータを解析します。解析が終わったら、Airtable API を使い、テーブルへ新しい行(新しいフォーム送信)を保存します。
async function submitHandler(request, env) {
if (request.method !== "POST") {
return new Response("Method Not Allowed", {
status: 405,
});
}
const body = await request.formData();
const { first_name, last_name, email, phone, subject, message } =
Object.fromEntries(body);
// The keys in "fields" are case-sensitive, and
// should exactly match the field names you set up
// in your Airtable table, such as "First Name".
const reqBody = {
fields: {
"First Name": first_name,
"Last Name": last_name,
Email: email,
"Phone Number": phone,
Subject: subject,
Message: message,
},
};
await createAirtableRecord(env, reqBody);
}
// Existing code
// export default ...この関数の大半はリクエストボディ(リクエストの一部として送られるデータ)の解析ですが、重要な点が 2 つあります。まず、この関数へ送られた HTTP メソッドが POST でない場合は、ステータスコード 405 Method Not Allowed ↗ の新しいレスポンスを返します。
変数 reqBody はフィールドの集まりで、Airtable テーブルの各列に対応するキーと値のペアです。reqBody を fields の集まりを持つオブジェクトとして整形すると、各フィールドに値がある新しいレコードがテーブルに作成されます。
次に createAirtableRecord(これから定義する関数)を呼び出します。createAirtableRecord 関数は body パラメーターを受け取ります。これは Airtable API が求める形式、つまり fields 配下にキーと値のペアを持つ JavaScript オブジェクトで、テーブルに作成する 1 件のレコードを表します。
async function createAirtableRecord(env, body) {
try {
const result = fetch(
`https://api.airtable.com/v0/${env.AIRTABLE_BASE_ID}/${encodeURIComponent(env.AIRTABLE_TABLE_NAME)}`,
{
method: "POST",
body: JSON.stringify(body),
headers: {
Authorization: `Bearer ${env.AIRTABLE_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
},
);
return result;
} catch (error) {
console.error(error);
}
}
// Existing code
// async function submitHandler
// export default ...Airtable へ認証付きリクエストを送るには、Airtable アカウント、base、テーブル名に関する 4 つの定数が必要です。AIRTABLE_ACCESS_TOKEN は暗号化する値なので、すでに wrangler secret で設定済みです。Airtable base ID と table name、および FORM_URL は、GitHub など公開できる値です。Wrangler の vars 機能を使い、Wrangler ファイルから公開用の環境変数を渡します。
Wrangler ファイルの末尾に vars テーブルを追加します。
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "workers-airtable-form",
"main": "src/index.js",
// Set this to today's date
"compatibility_date": "2026-09-20",
"vars": {
"AIRTABLE_BASE_ID": "exampleBaseId",
"AIRTABLE_TABLE_NAME": "Form Submissions"
}
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "workers-airtable-form"
main = "src/index.js"
# Set this to today's date
compatibility_date = "2026-09-20"
[vars]
AIRTABLE_BASE_ID = "exampleBaseId"
AIRTABLE_TABLE_NAME = "Form Submissions"これらのフィールドを設定したら、Workers のサーバーレス関数をデプロイし、フォームと通信できるようにします。まず Worker を公開します。
npx wrangler deployWorker プロジェクトは一意の URL にデプロイされます。例: https://workers-airtable-form.cloudflare.workers.dev。これがフロントエンドフォームの action 属性の前半です。後半はフォームハンドラーのパス /submit です。フロントエンド UI で、form タグを次のように設定します。
<form
action="https://workers-airtable-form.cloudflare.workers.dev/submit"
method="POST"
class="..."
>
<!-- The rest of your HTML form -->
</form>新しいフォームをデプロイしたあと(フォーム作成のヘルプが必要な場合は HTML フォーム のチュートリアルを参照)、フォームを送信すると、値がすぐに Airtable に表示されます。
このチュートリアルでは、フォーム送信を受け取り、Airtable へ永続化する Worker を作成しました。フォームデータの解析、環境変数の設定、Worker の外にある外部サービスへリクエストするための fetch API の使い方を学びました。