# Netlify Forms の上限：100 件を超えると何が起きるか、そして抜け出し方

> Netlify の旧プランはサイトごとにフォーム送信を計測して自動でアップグレードし、クレジットプランはサイトを一時停止することがあるので、フォームをバックエンドに移しましょう。

公開日 2026-10-25 · https://ikiform.com/ja/guides/website-builder-forms/netlify-forms-limit

Netlify の旧プランでは、各サイトに月 100 件のフォーム送信が含まれ、それを超えるとサイトが自動的に有料の Forms レベルにアップグレードされます。2025 年 9 月以降に作成したアカウント向けのクレジット制プランではフォームは無料ですが、無料のチームがクレジットを使い切ると、フォームも含めてすべてのサイトが一時停止されます。フォームを Ikiform に移すには、素の HTML でもどのフレームワークでも、Netlify の属性を削除して `action` を設定するだけです。

## Netlify ならではの違い

Netlify はサイトビルダーではなく、フォーム機能を内蔵したホスティングです。これが上限にも抜け出し方にも影響します。どの上限が適用されるかは、アカウントの作成時期で決まります。

| アカウント | Netlify のドキュメントの記載 | 送信の多いフォームにとっての意味 |
| --- | --- | --- |
| 旧プラン（2025 年 9 月 4 日より前に作成） | Forms Level 0 には、サイトごと・月ごとに 100 件の送信と 10 MB のアップロードが含まれます。超えるとサイトは 1,000 件の Forms Level 1 にアップグレードされ、請求サイクルの終わりに課金されます。それを超えると、追加の利用パッケージが 500 件ずつ加わります | スパムの波で、誰も決めていないのにサイトが有料レベルに上がることがあります。無料の旧プランでは、上限に達するとアカウントのすべてのサイトが一時停止されます |
| クレジット制プラン（それ以降に作成） | フォームの送信は無料かつ無制限で、レベルはありません | フォーム自体は無料です。ただし、無料のチームが月のクレジットを使い切ると Netlify はすべてのプロジェクトを一時停止し、一時停止したプロジェクトはフォームの送信を受け付けません |

Netlify 自身のドキュメントに、旧プランのアップグレードは自動であること、利用量が下のレベルを上回っている間は戻せないことが明記されています。何かを決める前に、Netlify のダッシュボードでチームのプランの種類とサイトのフォーム利用量を確認してください。

移行する 2 つ目の理由は、数字とは関係ありません。Netlify Forms は、デプロイされた HTML を読み取って動きます。

- フォームはデプロイ時に検出されます。React、Vue、Svelte が描画するフォームはその HTML に存在しないので、ビルドが見つけられるように非表示の静的なコピーを置き、`form-name` フィールド付きでそこに送信します。
- Next.js では、OpenNext アダプターがそのコピーを `public/` の静的ファイルとして必要とし、送信は Next.js のページではなくその静的ファイルに向ける必要があります。それがないまま React のコードに `data-netlify` があると、ビルドが失敗します。
- 送信は urlencoded か multipart でなければなりません。JSON は受け付けられません。
- フォームが動くのは、サイトが Netlify にデプロイされている間だけです。ホストを移すと、フォームも移すことになります。

図: 旧プランの Netlify サイトのフォーム利用量が 1 か月でどう増えるかと、Ikiform に送信すると何が変わるか

1. 旧プランでは、サイトは月の初めに 100 件の送信を含む Forms Level 0 から始まります。
2. 101 件目の送信が届きます。Netlify の利用量のドキュメントはサイトの利用量を対象にしているので、スパムの急増が上限を超えさせる原因になることもあります。
3. Netlify はサイトを 1,000 件の Forms Level 1 にアップグレードし、サイクルの終わりに請求します。
4. Level 1 を超えると、追加の利用パッケージが 500 件ずつ加わります。
5. フォームを Ikiform に送信するようにすると、ページは Netlify に置いたまま、送信は Ikiform のエンドポイントに向かいます。
6. Netlify Forms は送信を受け取らないので、数えるものもアップグレードするものもありません。

ホスティングは Netlify のままです。移るのはフォームの送信先だけで、それと一緒に計測も移ります。

## スタックごとにフォームを移す

コードを変える前に、Netlify のフォーム名ごとに Ikiform のフォームを 1 つ作り、その **Honeypot field** を `bot-field` に設定します。そうすれば既存の非表示の入力欄が、名前を変えずにそのままハニーポットとして働きます。スタックを選んでください。

**HTML**

Netlify 上の素の HTML なら、変更はいちばん少なくて済みます。Netlify の属性と `form-name` の入力欄を削除し、`action` をエンドポイントに向け、サンクスページのパスを完全な URL として `_redirect` に移します。`bot-field` の入力欄はハニーポットとして残します。

**変更前** (`contact.html`)

```html
<form name="contact" method="POST" action="/thanks" data-netlify="true" netlify-honeypot="bot-field">
  <input type="hidden" name="form-name" value="contact" />
  <p hidden><input name="bot-field" /></p>
  <label>Email <input type="email" name="email" required /></label>
  <label>Topic
    <select name="topic">
      <option value="question">A question</option>
      <option value="bug">Something is broken</option>
      <option value="work">Working together</option>
    </select>
  </label>
  <label>Message <textarea name="message" required></textarea></label>
  <button type="submit">Send</button>
</form>
```

**変更後** (`contact.html`)

```html
<form method="post" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx">
  <input name="bot-field" type="text" tabindex="-1" autocomplete="off" hidden />
  <label>Email <input type="email" name="email" required /></label>
  <label>Topic
    <select name="topic">
      <option value="question">A question</option>
      <option value="bug">Something is broken</option>
      <option value="work">Working together</option>
    </select>
  </label>
  <label>Message <textarea name="message" required></textarea></label>
  <input type="hidden" name="_redirect" value="https://your-site.netlify.app/thanks" />
  <button type="submit">Send</button>
</form>
```

**Next.js**

Netlify 上の Next.js のフォームは、`public/__forms.html` のような `public/` の静的なコピーにコンポーネントから送信することでしか Netlify Forms と連携できませんでした。そのファイルを削除し、`NETLIFY_NEXT_VERIFY_FORMS` の設定があれば外して、コンポーネントから Ikiform に送信します。`action` があるので、フォームは JavaScript なしでも送信できます。

`app/contact/contact-form.tsx`:

```tsx
"use client";

import { type FormEvent, useState } from "react";

const ENDPOINT = "https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx";

export function ContactForm() {
  const [state, setState] = useState<"idle" | "sending" | "sent">("idle");
  const [error, setError] = useState("");

  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setState("sending");
    setError("");
    try {
      const response = await fetch(ENDPOINT, {
        method: "POST",
        headers: { Accept: "application/json" },
        body: new FormData(event.currentTarget),
      });
      const result = await response.json();
      if (result.ok) return setState("sent");
      setError(result.error.fields?.message?.[0] ?? result.error.fields?.email?.[0] ?? result.error.message);
    } catch {
      setError("Couldn't send. Check your connection and try again.");
    }
    setState("idle");
  }

  if (state === "sent") return <p role="status">Thanks. We read every message and reply within a day.</p>;

  return (
    <form action={ENDPOINT} method="post" onSubmit={onSubmit}>
      <input name="bot-field" type="text" tabIndex={-1} autoComplete="off" hidden />
      <label htmlFor="email">Email</label>
      <input id="email" name="email" type="email" required />
      <label htmlFor="topic">Topic</label>
      <select id="topic" name="topic" defaultValue="question">
        <option value="question">A question</option>
        <option value="bug">Something is broken</option>
        <option value="work">Working together</option>
      </select>
      <label htmlFor="message">Message</label>
      <textarea id="message" name="message" required />
      {error ? <p role="alert">{error}</p> : null}
      <button disabled={state === "sending"}>{state === "sending" ? "Sending" : "Send"}</button>
    </form>
  );
}
```

**Astro**

静的な Astro のページなら、JavaScript はまったく要りません。フォームから `data-netlify` を削除し、エンドポイントを `action` に設定して、`astro.config.mjs` の `site` からリダイレクト先を組み立てます。ページはプリレンダーのままでかまいません。

`src/pages/contact.astro`:

```astro
---
const endpoint = "https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx";
const thanksUrl = new URL("/thanks", Astro.site).href;
---

<form method="post" action={endpoint}>
  <input name="bot-field" type="text" tabindex="-1" autocomplete="off" hidden />
  <label for="email">Email</label>
  <input id="email" name="email" type="email" required />
  <label for="topic">Topic</label>
  <select id="topic" name="topic">
    <option value="question">A question</option>
    <option value="bug">Something is broken</option>
    <option value="work">Working together</option>
  </select>
  <label for="message">Message</label>
  <textarea id="message" name="message" required></textarea>
  <input type="hidden" name="_redirect" value={thanksUrl} />
  <button>Send</button>
</form>
```

**TanStack Start**

Netlify 上の TanStack Start アプリはフォームを React で描画するので、Netlify のデプロイ時の検出では見つけられませんでした。代わりにサーバー関数経由で送信し、非表示の静的なコピーは削除します。Netlify でサイトの環境変数に `IKIFORM_SECRET_KEY` を設定します。関数はブラウザーの `Origin` ヘッダーを引き継ぐので、ワークスペースにプランがなくても `localhost` からの送信は無料のテストとして数えられます。

`src/routes/contact.tsx`:

```tsx
import { createFileRoute } from "@tanstack/react-router";
import { createServerFn, useServerFn } from "@tanstack/react-start";
import { getRequestHeader } from "@tanstack/react-start/server";
import { type FormEvent, useState } from "react";

const sendMessage = createServerFn({ method: "POST" })
  .validator((data: unknown) => {
    if (!(data instanceof FormData)) throw new Error("Expected form data");
    return {
      email: String(data.get("email") ?? "").trim(),
      topic: String(data.get("topic") ?? "question"),
      message: String(data.get("message") ?? "").trim(),
      "bot-field": String(data.get("bot-field") ?? ""),
    };
  })
  .handler(async ({ data }) => {
    const origin = getRequestHeader("origin");
    const response = await fetch("https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.IKIFORM_SECRET_KEY}`,
        ...(origin ? { Origin: origin } : {}),
      },
      body: JSON.stringify(data),
    });
    const result = await response.json();
    return result.ok ? { sent: true, error: "" } : { sent: false, error: String(result.error.message) };
  });

export const Route = createFileRoute("/contact")({ component: Contact });

function Contact() {
  const send = useServerFn(sendMessage);
  const [state, setState] = useState({ sent: false, error: "" });
  const [pending, setPending] = useState(false);

  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setPending(true);
    try {
      setState(await send({ data: new FormData(event.currentTarget) }));
    } catch {
      setState({ sent: false, error: "Couldn't send. Try again." });
    } finally {
      setPending(false);
    }
  }

  if (state.sent) return <p role="status">Thanks. We read every message and reply within a day.</p>;

  return (
    <form method="post" onSubmit={onSubmit}>
      <input name="bot-field" type="text" tabIndex={-1} autoComplete="off" hidden />
      <label htmlFor="email">Email</label>
      <input id="email" name="email" type="email" required />
      <label htmlFor="topic">Topic</label>
      <select id="topic" name="topic" defaultValue="question">
        <option value="question">A question</option>
        <option value="bug">Something is broken</option>
        <option value="work">Working together</option>
      </select>
      <label htmlFor="message">Message</label>
      <textarea id="message" name="message" required />
      {state.error ? <p role="alert">{state.error}</p> : null}
      <button disabled={pending}>{pending ? "Sending" : "Send"}</button>
    </form>
  );
}
```

**React Router**

フレームワークモードの React Router では、ルートの `action` が送信を転送します。`FormData` はそのまま渡されるので `bot-field` は Ikiform のハニーポットのチェックに届き、ブラウザーの `Origin` ヘッダーも一緒に送られるので `localhost` からの送信はテストとして数えられます。Netlify 用に置いていた静的なコピーは削除します。

`app/routes/contact.tsx`:

```tsx
import { data, Form, useNavigation } from "react-router";
import type { Route } from "./+types/contact";

export async function action({ request }: Route.ActionArgs) {
  const form = await request.formData();
  const origin = request.headers.get("origin");
  const response = await fetch("https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx", {
    method: "POST",
    headers: {
      Accept: "application/json",
      Authorization: `Bearer ${process.env.IKIFORM_SECRET_KEY}`,
      ...(origin ? { Origin: origin } : {}),
    },
    body: form,
  });
  const result = await response.json();
  if (result.ok) return { sent: true, error: "" };
  return data({ sent: false, error: String(result.error.message) }, { status: response.status });
}

export default function Contact({ actionData }: Route.ComponentProps) {
  const sending = useNavigation().state === "submitting";
  if (actionData?.sent) return <p role="status">Thanks. We read every message and reply within a day.</p>;

  return (
    <Form method="post">
      <input name="bot-field" type="text" tabIndex={-1} autoComplete="off" hidden />
      <label htmlFor="email">Email</label>
      <input id="email" name="email" type="email" required />
      <label htmlFor="topic">Topic</label>
      <select id="topic" name="topic" defaultValue="question">
        <option value="question">A question</option>
        <option value="bug">Something is broken</option>
        <option value="work">Working together</option>
      </select>
      <label htmlFor="message">Message</label>
      <textarea id="message" name="message" required />
      {actionData?.error ? <p role="alert">{actionData.error}</p> : null}
      <button disabled={sending}>{sending ? "Sending" : "Send"}</button>
    </Form>
  );
}
```

**SvelteKit**

Netlify 上の SvelteKit のページは、自前のフォームアクションなしでブラウザーから直接送信できます。`action` 属性があるので、ハイドレーション前でもフォームは動きます。Netlify 用に追加したフォームのプリレンダー済みのコピーは削除します。

`src/routes/contact/+page.svelte`:

```svelte
<script lang="ts">
  const ENDPOINT = "https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx";

  let sent = $state(false);
  let sending = $state(false);
  let error = $state("");

  async function send(event: SubmitEvent) {
    event.preventDefault();
    sending = true;
    error = "";
    try {
      const response = await fetch(ENDPOINT, {
        method: "POST",
        headers: { Accept: "application/json" },
        body: new FormData(event.currentTarget as HTMLFormElement),
      });
      const result = await response.json();
      if (result.ok) sent = true;
      else error = result.error.message;
    } catch {
      error = "Couldn't send. Check your connection and try again.";
    }
    sending = false;
  }
</script>

{#if sent}
  <p role="status">Thanks. We read every message and reply within a day.</p>
{:else}
  <form method="post" action={ENDPOINT} onsubmit={send}>
    <input name="bot-field" type="text" tabindex="-1" autocomplete="off" hidden />
    <label for="email">Email</label>
    <input id="email" name="email" type="email" required />
    <label for="topic">Topic</label>
    <select id="topic" name="topic">
      <option value="question">A question</option>
      <option value="bug">Something is broken</option>
      <option value="work">Working together</option>
    </select>
    <label for="message">Message</label>
    <textarea id="message" name="message" required></textarea>
    {#if error}<p role="alert">{error}</p>{/if}
    <button disabled={sending}>{sending ? "Sending" : "Send"}</button>
  </form>
{/if}
```

**Nuxt**

Nuxt ではコンポーネントがブラウザーから `$fetch` で送信するので、デプロイするサーバールートはありません。`$fetch` は `2xx` 以外の応答で例外を投げ、Ikiform のエラーエンベロープはエラーの `data` に入っています。`public/` の非表示の静的フォームと `form-name` フィールドを削除します。

`app/components/ContactForm.vue`:

```vue
<script setup lang="ts">
const ENDPOINT = "https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx";
const sent = ref(false);
const sending = ref(false);
const error = ref("");

async function send(event: Event) {
  sending.value = true;
  error.value = "";
  try {
    await $fetch(ENDPOINT, {
      method: "POST",
      headers: { Accept: "application/json" },
      body: new FormData(event.target as HTMLFormElement),
    });
    sent.value = true;
  } catch (failure) {
    const data = (failure as { data?: { error?: { message?: string } } }).data;
    error.value = data?.error?.message ?? "Couldn't send. Check your connection and try again.";
  } finally {
    sending.value = false;
  }
}
</script>

<template>
  <p v-if="sent" role="status">Thanks. We read every message and reply within a day.</p>
  <form v-else :action="ENDPOINT" method="post" @submit.prevent="send">
    <input name="bot-field" type="text" tabindex="-1" autocomplete="off" hidden />
    <label for="email">Email</label>
    <input id="email" name="email" type="email" required />
    <label for="topic">Topic</label>
    <select id="topic" name="topic">
      <option value="question">A question</option>
      <option value="bug">Something is broken</option>
      <option value="work">Working together</option>
    </select>
    <label for="message">Message</label>
    <textarea id="message" name="message" required></textarea>
    <p v-if="error" role="alert">{{ error }}</p>
    <button :disabled="sending">{{ sending ? "Sending" : "Send" }}</button>
  </form>
</template>
```

**React**

Netlify 上の React のシングルページアプリは、`form-name` フィールド付きで urlencoded のデータを `/` に送信し、検出用に `index.html` に静的なコピーが必要でした。今度は `FormData` をエンドポイントに送信します。変わるのはリクエストだけです。

**変更前** (`ContactForm.tsx`)

```tsx
const body = new URLSearchParams(new FormData(event.currentTarget) as unknown as Record<string, string>);
body.set("form-name", "contact");
await fetch("/", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: body.toString(),
});
```

**変更後** (`ContactForm.tsx`)

```tsx
const response = await fetch("https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx", {
  method: "POST",
  headers: { Accept: "application/json" },
  body: new FormData(event.currentTarget),
});
const result = await response.json();
if (!result.ok) setError(result.error.message);
```

Netlify に何も送信しなくなったら、`index.html` から非表示の `<form netlify>` を削除します。

**Vue**

Vue の単一ファイルコンポーネントでの、同じブラウザー側の送信です。Netlify に検出させるための非表示のフォームを `index.html` から削除します。

`src/components/ContactForm.vue`:

```vue
<script setup lang="ts">
import { ref } from "vue";

const ENDPOINT = "https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx";
const state = ref<"idle" | "sending" | "sent">("idle");
const error = ref("");

async function send(event: Event) {
  state.value = "sending";
  error.value = "";
  try {
    const response = await fetch(ENDPOINT, {
      method: "POST",
      headers: { Accept: "application/json" },
      body: new FormData(event.target as HTMLFormElement),
    });
    const result = await response.json();
    if (result.ok) {
      state.value = "sent";
      return;
    }
    error.value = result.error.message;
  } catch {
    error.value = "Couldn't send. Check your connection and try again.";
  }
  state.value = "idle";
}
</script>

<template>
  <p v-if="state === 'sent'" role="status">Thanks. We read every message and reply within a day.</p>
  <form v-else :action="ENDPOINT" method="post" @submit.prevent="send">
    <input name="bot-field" type="text" tabindex="-1" autocomplete="off" hidden />
    <label for="email">Email</label>
    <input id="email" name="email" type="email" required />
    <label for="topic">Topic</label>
    <select id="topic" name="topic">
      <option value="question">A question</option>
      <option value="bug">Something is broken</option>
      <option value="work">Working together</option>
    </select>
    <label for="message">Message</label>
    <textarea id="message" name="message" required></textarea>
    <p v-if="error" role="alert">{{ error }}</p>
    <button :disabled="state === 'sending'">{{ state === "sending" ? "Sending" : "Send" }}</button>
  </form>
</template>
```

> TanStack Start と React Router の版は、自分のサーバーから送信します。サーバー側の版はシークレットキー付きで送信するので、Ikiform は **Allowed domains** と人間確認をスキップします。その場合はすべての送信がサーバーの IP から来るため、訪問者ごとに 1 分あたり 5 件という Standard の制限が、すべての訪問者をまとめて数えてしまいます。サーバー経由で送信するフォームでは Relaxed か Custom の[レート制限](https://ikiform.com/ja/docs/rate-limits.md)を選び、`IKIFORM_SECRET_KEY` はサーバー専用の環境変数に置いてください。

どの版も Netlify と同じフィールド名を使うので、通知メールや CSV の列は見慣れたままです。[Netlify Forms との比較](https://ikiform.com/alternatives/netlify-forms)に、`data-netlify-recaptcha` やファイルの入力欄も含めた属性の対応表があります。

## デプロイプレビューと許可ドメイン

Netlify はプルリクエストごとに `deploy-preview-42--your-site.netlify.app` のような専用のアドレスを付けます。これは `your-site.netlify.app` のサブドメインではないので、**Allowed domains** にサイトのアドレスを入れてもプレビューはカバーされず、プレビューからの送信は `origin_mismatch` でスパムになります。

- 本番用に `your-site.netlify.app` と独自ドメインを追加します。
- テストしている間だけ特定のプレビューのホストを追加し、終わったら削除します。
- `netlify.app` 単体は追加しないでください。Netlify 上のすべてのサイトがあなたのフォームに送信できるようになってしまいます。
- または、環境変数を使ってプレビューを許可ドメインのない 2 つ目の Ikiform のフォームに向け、本番は厳格なままにします。

## 送信を失わずに切り替える

1. サイトの **Forms** セクションから、フォームごとの過去の送信データを CSV でダウンロードします。Ikiform にはインポート機能がありません。
2. 新しいフォームをプレビューにデプロイしてテストを送ります。Ikiform のダッシュボードでフィールド名を確認します。
3. 本番にマージし、本番のドメインからもう一度テストを送ります。
4. Netlify の送信 Webhook は Ikiform の [Webhook](https://ikiform.com/ja/docs/webhooks.md) に置き換えます。Netlify は JWS トークンで署名し、Ikiform は Standard Webhooks のヘッダーを使うので、検証処理も変わります。
5. 数日間 Netlify に送信が届かなくなったら、サイトの Forms 設定でフォームの検出をオフにします。

> Netlify はファイルアップロードを受け付け、すべての送信に Akismet をかけます。Ikiform はファイルアップロードにまだ対応していません。ファイル付きの送信には `422 files_not_supported` が返ります。ファイルが必要なフォームがあれば、そのフォームだけ Netlify Forms に残し、残りを移してください。

## Netlify で動作を確認する

1. フォームの **Allowed domains** に自分のサイトのドメインを追加し、開発中は `localhost` も追加します。空のままにすると、どこからの送信も受け付けます。
2. プレビューをデプロイし、そのホストを追加して、そこからフォームを送信します。
3. ダッシュボードで **Submissions** を開きます。送ったすべてのフィールドを含む新しい送信データがあります。
4. フィールドが `email`、`topic`、`message` で、`form-name` も `bot-field` もないことを確認します。
5. Netlify でサイトの **Forms** タブを開き、テストがそこにないことを確認します。
6. `bot-field` を埋めて 1 回送信します。スパムとして保存され、何も送られません。
7. 通知の各受信者の受信トレイを確認します。それぞれにフィールド入りのメールが届き、フォームに `email` フィールドがあれば **Reply** で送信者に返信できます。

## ハマりどころ

| 問題 | 対処法 |
| --- | --- |
| Ikiform に `form-name` フィールドが表示される | 非表示の `form-name` の入力欄がまだフォームに残っているか、コードがまだ設定しています。削除してください。Ikiform は URL でフォームを識別します。 |
| フォームに関するエラーで Next.js のビルドが失敗する | React のコードに `netlify` か `data-netlify` の属性がまだ残っています。`public/__forms.html` と一緒に削除してください。 |
| プレビューからの送信がスパムになる | プレビューのホストが **Allowed domains** にありません。テスト中だけ追加するか、プレビュー用に 2 つ目のフォームを使ってください。 |
| 本物も含めて、すべての送信がスパムになる | 入力欄は `bot-field` なのに **Honeypot field** が `_gotcha` のまま、またはその逆です。両者を合わせてください。 |
| `422 files_not_supported` | フォームの `<input type="file">` でファイルが選択されています。ファイルアップロードにはまだ対応していません。入力欄を削除するか、代わりにリンクを尋ねてください。 |
| `429 rate_limited` | 1 人の訪問者がフォームのレート制限を超えて送信しました。Standard では訪問者ごとに 1 分あたり 5 件までです。`Retry-After` まで待つか、共有の IP 1 つから送信するフォームには Relaxed か Custom を選んでください。 |

## よくある質問

### Netlify のサイトがフォーム送信 100 件を超えるとどうなりますか？

旧プランでは、Netlify はサイトを月 1,000 件の送信を含む Forms Level 1 にアップグレードし、請求サイクルの終わりに課金します。無料の旧プランでは、上限に達するとアップグレードするまでアカウントのすべてのサイトが一時停止されます。

### 新しいクレジット制プランでは Netlify Forms は無料ですか？

Netlify のドキュメントでは、クレジット制プランのフォーム送信は無料かつ無制限とされています。落とし穴はサイトそのものです。無料のチームが月のクレジットを使い切ると、プロジェクトは一時停止され、フォームの送信を受け付けません。

### ホスティングは Netlify のまま、フォームに Ikiform を使えますか？

はい。Ikiform はページがどこでホストされていてもかまいません。フォームから Netlify の属性を削除して action を Ikiform のエンドポイントにすれば、Netlify Forms はそのフォームを認識しなくなります。

### React や Next.js では、まだ非表示の静的フォームが必要ですか？

いいえ。あのコピーは、Netlify のデプロイ処理がフォームを見つけるためだけにあります。Ikiform は URL で送信を受け取るので、コピーを削除してコンポーネントから送信してください。

### Ikiform は無料ですか？

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

## その他のガイド

- [ビルダーのフォームを卒業する](https://ikiform.com/ja/guides/website-builder-forms.md): Webflow、Netlify、Carrd、Framer のフォームが上限や機能不足に当たったら、デザインしたフォームはそのままに、送信先をフォームバックエンドに変えましょう。
- [Webflow の送信上限](https://ikiform.com/ja/guides/website-builder-forms/webflow-submission-limit.md): Webflow の無料 Starter プランはサイトごとに 50 件で送信の受け付けが止まり、エクスポートしたサイトでは一切処理されないので、Form Block の送信先を Ikiform に向けましょう。
- [Framer のフォーム](https://ikiform.com/ja/guides/website-builder-forms/framer-forms.md): Framer のフォームはメール、Sheets、Webhook に送れます。保存とフィルタリング、チームへの通知、送信先の追加がほしいなら Ikiform を Webhook にします。
- [Carrd のフォーム](https://ikiform.com/ja/guides/website-builder-forms/carrd-forms.md): Carrd のお問い合わせフォームはメールで届けるだけで、カスタムフォームには Pro Plus が必要です。すべての送信を保存するには、Plus なら Send to URL、Standard なら HTML の埋め込みを使います。
