# Netlify-Forms-Limit: was bei 100 Einsendungen passiert und wie du rauskommst

> Legacy-Tarife von Netlify messen Formulareinsendungen pro Site und stufen dich automatisch hoch, und Credit-Tarife können die Site pausieren. Verlege das Formular deshalb auf ein Backend.

Veröffentlicht am 2026-10-25 · https://ikiform.com/de/guides/website-builder-forms/netlify-forms-limit

In den Legacy-Tarifen von Netlify enthält jede Site 100 Formulareinsendungen pro Monat, und wer darüber kommt, wird automatisch auf eine bezahlte Forms-Stufe hochgestuft. In den Credit-Tarifen für Accounts, die seit September 2025 erstellt wurden, sind Formulare kostenlos, aber bei einem kostenlosen Team, dem die Credits ausgehen, wird jede Site pausiert, Formulare eingeschlossen. Das Formular zu Ikiform zu verlegen heißt, die Netlify-Attribute zu entfernen und die `action` zu setzen, in reinem HTML oder jedem Framework.

## Was bei Netlify anders ist

Netlify ist kein Site-Builder, sondern ein Host mit eingebauten Formularen. Das prägt sowohl das Limit als auch den Ausweg. Welches Limit gilt, hängt davon ab, wann dein Account erstellt wurde:

| Account | Was die Doku von Netlify sagt | Was es für ein viel genutztes Formular bedeutet |
| --- | --- | --- |
| Legacy-Tarife, erstellt vor dem 4. September 2025 | Forms Level 0 enthält 100 Einsendungen und 10 MB Uploads pro Site und Monat. Wer darüber kommt, wird auf Forms Level 1 mit 1.000 Einsendungen hochgestuft, abgerechnet am Ende des Abrechnungszeitraums. Darüber hinaus fügen Zusatzpakete je 500 hinzu | Eine Spamwelle kann eine Site auf eine bezahlte Stufe heben, ohne dass jemand das entschieden hat. In der kostenlosen Legacy-Stufe pausiert das Erreichen eines Limits jede Site des Accounts |
| Credit-Tarife, seitdem erstellt | Formulareinsendungen sind kostenlos und unbegrenzt, ohne Stufen | Das Formular selbst kostet nichts. Aber wenn ein kostenloses Team seine monatlichen Credits verbraucht, pausiert Netlify alle seine Projekte, und pausierte Projekte empfangen keine Formulareinsendungen |

Die Doku von Netlify sagt klar, dass die Legacy-Hochstufung automatisch erfolgt und dass du nicht zurückstufen kannst, solange die Nutzung über der niedrigeren Stufe liegt. Prüf den Tariftyp deines Teams und die Formularnutzung der Site im Netlify-Dashboard, bevor du etwas entscheidest.

Der zweite Grund für den Wechsel hat nichts mit Zahlen zu tun. Netlify Forms funktioniert, indem es dein deploytes HTML liest:

- Formulare werden beim Deploy gefunden. Ein Formular, das React, Vue oder Svelte rendert, existiert in diesem HTML nicht, also hältst du eine versteckte statische Kopie für den Build bereit und sendest mit einem `form-name`-Feld daran.
- Bei Next.js braucht der OpenNext-Adapter diese Kopie als statische Datei in `public/`, und der Post muss an diese statische Datei gehen, nicht an eine Next.js-Seite. Der Build scheitert, wenn `data-netlify` ohne sie in React-Code vorkommt.
- Einsendungen müssen urlencoded oder multipart sein. JSON wird nicht akzeptiert.
- Das Formular funktioniert nur, solange die Site auf Netlify deployt ist. Den Host wechseln heißt, die Formulare umzuziehen.

Diagramm: Wie die Formularnutzung einer Legacy-Netlify-Site im Monat steigt und was das Senden an Ikiform ändert

1. In einem Legacy-Tarif startet eine Site den Monat auf Forms Level 0 mit 100 enthaltenen Einsendungen.
2. Einsendung 101 kommt an. Die Nutzungsdoku von Netlify beschreibt die Nutzung der Site, also kann ein Spamschub genau das sein, was sie über die Grenze bringt.
3. Netlify stuft die Site auf Forms Level 1 mit 1.000 Einsendungen hoch und rechnet am Ende des Zeitraums ab.
4. Über Level 1 hinaus fügen Zusatzpakete je 500 Einsendungen hinzu.
5. Sendet das Formular an Ikiform, liegt die Seite weiter auf Netlify, aber der Post geht an den Ikiform-Endpunkt.
6. Netlify Forms empfängt den Post nie, also gibt es nichts zu zählen oder hochzustufen.

Das Hosting bleibt auf Netlify. Nur das Ziel des Formulars zieht um und damit die Messung.

## Das Formular umziehen, Stack für Stack

Bevor du Code änderst, erstelle ein Ikiform-Formular pro Netlify-Formularname und setze sein **Honeypot field** auf `bot-field`. Dann funktioniert dein bestehender versteckter Input weiter als Honeypot, ohne Umbenennung. Wähle deinen Stack:

**HTML**

Reines HTML auf Netlify braucht die wenigsten Änderungen. Lösche die Netlify-Attribute und den `form-name`-Input, richte `action` auf den Endpunkt und verschiebe den Pfad der Dankeseite als vollständige URL in `_redirect`. Der `bot-field`-Input bleibt dein Honeypot.

**Vorher** (`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>
```

**Nachher** (`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**

Auf Netlify funktionierte ein Next.js-Formular mit Netlify Forms nur über eine statische Kopie in `public/`, etwa `public/__forms.html`, an die deine Komponente sendete. Lösche diese Datei, entferne jede Einstellung `NETLIFY_NEXT_VERIFY_FORMS` und sende aus der Komponente an Ikiform. Dank seiner `action` sendet das Formular auch ohne 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**

Eine statische Astro-Seite braucht überhaupt kein JavaScript. Entferne `data-netlify` aus dem Formular, setze den Endpunkt als `action` und baue die Weiterleitung aus `site` in `astro.config.mjs`. Die Seite kann vorgerendert bleiben.

`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**

Eine TanStack-Start-App auf Netlify rendert Formulare in React, was die Erkennung beim Deploy von Netlify nicht sehen konnte. Sende stattdessen über eine Server-Funktion und lass die versteckte statische Kopie weg. Setze `IKIFORM_SECRET_KEY` in den Umgebungsvariablen der Site in Netlify. Die Funktion reicht den `Origin`-Header des Browsers weiter, sodass Posts von `localhost` als kostenlose Tests zählen, bevor dein Workspace einen Tarif hat.

`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**

Mit React Router im Framework-Modus leitet die `action` der Route den Post weiter. Die `FormData` geht unverändert durch, sodass `bot-field` Ikiforms Honeypot-Prüfung erreicht, und der `Origin`-Header des Browsers geht mit, sodass `localhost`-Posts als Tests zählen. Entferne die statische Kopie, die du für Netlify behalten hast.

`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**

Eine SvelteKit-Seite auf Netlify kann direkt aus dem Browser senden, ohne eigene Form Action. Das `action`-Attribut hält das Formular vor der Hydration funktionsfähig. Lösche jede vorgerenderte Kopie des Formulars, die du für Netlify ergänzt hast.

`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**

In Nuxt sendet die Komponente mit `$fetch` aus dem Browser, also gibt es keine Server-Route zu deployen. `$fetch` wirft bei einer Antwort außerhalb von `2xx`, und Ikiforms Fehlerhülle liegt in `data` des Fehlers. Entferne das versteckte statische Formular aus `public/` und das `form-name`-Feld.

`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**

Eine React-Single-Page-App auf Netlify sendete urlencoded Daten mit einem `form-name`-Feld an `/` und brauchte für die Erkennung eine statische Kopie in `index.html`. Jetzt sendet sie die `FormData` an den Endpunkt. Nur der Request ändert sich:

**Vorher** (`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(),
});
```

**Nachher** (`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);
```

Lösche das versteckte `<form netlify>` aus `index.html`, sobald nichts mehr an Netlify sendet.

**Vue**

Derselbe Post aus dem Browser in einer Vue-Single-File-Component. Entferne das versteckte Formular aus `index.html`, mit dem Netlify es erkannt hat.

`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>
```

> Die Versionen für TanStack Start und React Router senden von deinem Server. Die serverseitigen Versionen senden mit einem Secret Key, also überspringt Ikiform **Allowed domains** und seine Menschlichkeitsprüfung. Jeder Post kommt dann von der IP deines Servers, und das Standard-Limit von 5 pro Minute pro Besucher zählt alle deine Besucher zusammen. Wähle für ein Formular, das du über einen Server sendest, das [Rate-Limit](https://ikiform.com/de/docs/rate-limits.md) Relaxed oder Custom und halte `IKIFORM_SECRET_KEY` in Umgebungsvariablen, die nur der Server sieht.

Jede Version behält dieselben Feldnamen wie bei Netlify, sodass Benachrichtigungs-E-Mails und CSV-Spalten vertraut aussehen. Der [Vergleich mit Netlify Forms](https://ikiform.com/alternatives/netlify-forms) enthält die vollständige Zuordnung der Attribute, einschließlich `data-netlify-recaptcha` und Datei-Inputs.

## Deploy Previews und erlaubte Domains

Netlify gibt jedem Pull Request eine eigene Adresse, etwa `deploy-preview-42--your-site.netlify.app`. Das ist keine Subdomain von `your-site.netlify.app`, also deckt die Adresse deiner Site unter **Allowed domains** keine Previews ab, und Posts aus Previews landen mit `origin_mismatch` im Spam.

- Füge `your-site.netlify.app` und deine eigene Domain für die Produktion hinzu.
- Füge einen bestimmten Preview-Host hinzu, solange du ihn testest, und entferne ihn dann.
- Füge nicht `netlify.app` allein hinzu. Jede Site auf Netlify dürfte dann an dein Formular senden.
- Oder richte Previews über eine Umgebungsvariable auf ein zweites Ikiform-Formular ohne erlaubte Domains und halte die Produktion streng.

## Umstellen, ohne Einsendungen zu verlieren

1. Lade die bisherigen Einsendungen jedes Formulars als CSV im Bereich **Forms** der Site herunter. Ikiform hat keinen Import.
2. Deploye das neue Formular in eine Preview und sende einen Test. Prüfe die Feldnamen im Ikiform-Dashboard.
3. Merge in die Produktion und sende einen weiteren Test von der Live-Domain.
4. Ersetze jeden ausgehenden Netlify-Webhook durch einen Ikiform-[Webhook](https://ikiform.com/de/docs/webhooks.md). Netlify signiert mit einem JWS-Token; Ikiform nutzt Header nach Standard Webhooks, also ändert sich auch dein Verifizierer.
5. Wenn ein paar Tage lang kein Post mehr Netlify erreicht hat, schalte die Formularerkennung in den Forms-Einstellungen der Site aus.

> Netlify akzeptiert Datei-Uploads und lässt Akismet über jede Einsendung laufen. Datei-Uploads werden noch nicht unterstützt. Ein Post mit einer Datei bekommt `422 files_not_supported`. Braucht ein Formular Dateien, lass dieses eine Formular bei Netlify Forms und zieh den Rest um.

## Prüfen, dass es auf Netlify funktioniert

1. Füge unter **Allowed domains** des Formulars die Domain deiner Site hinzu, plus `localhost`, während du entwickelst. Lass das Feld leer, um Posts von überall anzunehmen.
2. Deploye eine Preview, füge ihren Host hinzu und sende das Formular von dort ab.
3. Öffne **Submissions** im Dashboard. Die neue Einsendung ist da, mit jedem Feld, das du gesendet hast.
4. Prüfe, dass die Felder `email`, `topic` und `message` sind, ohne `form-name` und ohne `bot-field`.
5. Öffne den Tab **Forms** der Site in Netlify und prüfe, dass der Test nicht dort ist.
6. Sende einmal mit ausgefülltem `bot-field`. Er wird als Spam gespeichert und sendet nichts.
7. Prüfe das Postfach jedes Benachrichtigungsempfängers. Jeder bekommt eine E-Mail mit den Feldern, und **Reply** geht an den Absender, wenn das Formular ein `email`-Feld hat.

## Stolperfallen

| Problem | Was zu tun ist |
| --- | --- |
| Ein `form-name`-Feld taucht in Ikiform auf | Der versteckte `form-name`-Input ist noch im Formular, oder dein Code setzt ihn noch. Entferne ihn; Ikiform erkennt das Formular an der URL. |
| Der Next.js-Build scheitert mit einer Meldung zu Formularen | Ein Attribut `netlify` oder `data-netlify` steht noch in deinem React-Code. Entferne es zusammen mit `public/__forms.html`. |
| Previews senden in den Spam | Der Preview-Host steht nicht unter **Allowed domains**. Füge ihn beim Testen hinzu oder nutze ein zweites Formular für Previews. |
| Jeder Post wird als Spam markiert, auch echte | **Honeypot field** ist noch `_gotcha`, während dein Input `bot-field` heißt, oder umgekehrt. Bring sie in Einklang. |
| `422 files_not_supported` | Das Formular hat ein `<input type="file">` mit ausgewählter Datei. Datei-Uploads werden noch nicht unterstützt; entferne das Eingabefeld oder bitte stattdessen um einen Link. |
| `429 rate_limited` | Ein Besucher hat mehr gesendet, als das Rate-Limit des Formulars erlaubt. Standard erlaubt 5 pro Minute und Besucher. Warte `Retry-After` ab oder wähle Relaxed oder Custom für Formulare, die von einer gemeinsamen IP aus senden. |

## Fragen

### Was passiert, wenn eine Netlify-Site 100 Formulareinsendungen überschreitet?

In Legacy-Tarifen stuft Netlify die Site auf Forms Level 1 hoch, das 1.000 Einsendungen pro Monat enthält, und rechnet am Ende des Abrechnungszeitraums ab. In der kostenlosen Legacy-Stufe pausiert das Erreichen eines Limits jede Site des Accounts, bis du upgradest.

### Sind Netlify Forms in den neuen Credit-Tarifen kostenlos?

Laut Doku von Netlify sind Formulareinsendungen in Credit-Tarifen kostenlos und unbegrenzt. Der Haken ist die Site selbst: Wenn einem kostenlosen Team die monatlichen Credits ausgehen, werden seine Projekte pausiert und empfangen keine Formulareinsendungen.

### Kann ich weiter auf Netlify hosten und Ikiform für Formulare nutzen?

Ja. Ikiform ist egal, wo die Seite gehostet ist. Entferne die Netlify-Attribute aus dem Formular, setze seine Action auf deinen Ikiform-Endpunkt, und Netlify Forms sieht es nicht mehr.

### Brauche ich für React oder Next.js noch ein verstecktes statisches Formular?

Nein. Diese Kopie gibt es nur, damit der Deploy-Schritt von Netlify das Formular findet. Ikiform nimmt Posts an einer URL an, also lösche die Kopie und sende aus deiner Komponente.

### Ist Ikiform kostenlos?

Nein, es gibt keinen kostenlosen Tarif. Testen ist kostenlos: Du kannst 50 Testeinsendungen pro Monat von localhost senden, bevor du zahlst. Für den Livebetrieb startet Pro bei $6/Monat für 500 Einsendungen, oder du zahlst einmalig 10.000 Einsendungen für $49 oder 50.000 Einsendungen für $149, mit Guthaben, das nie verfällt.

## Weitere Anleitungen

- [Grenzen von Baukasten-Formularen](https://ikiform.com/de/guides/website-builder-forms.md): Wenn Formulare in Webflow, Netlify, Carrd oder Framer an ein Limit oder eine fehlende Funktion stoßen, behalte dein Formular und richte es auf ein Formular-Backend aus.
- [Webflow-Einsendungslimit](https://ikiform.com/de/guides/website-builder-forms/webflow-submission-limit.md): Der kostenlose Starter-Tarif von Webflow hört nach 50 Formulareinsendungen pro Site auf zu sammeln, und exportierte Sites bekommen gar keine. Richte den Form Block deshalb auf Ikiform aus.
- [Framer-Formulare](https://ikiform.com/de/guides/website-builder-forms/framer-forms.md): Framer-Formulare senden bereits an E-Mail, Sheets oder einen Webhook; ergänze Ikiform als Webhook für gespeicherte, gefilterte Einsendungen, Team-Benachrichtigungen und weitere Ziele.
- [Carrd-Formulare](https://ikiform.com/de/guides/website-builder-forms/carrd-forms.md): Das Kontaktformular von Carrd schickt dir nur E-Mails, und eigene Formulare brauchen Pro Plus. Nutze deshalb Send to URL in Plus oder ein HTML-Embed in Standard, um jede Einsendung zu speichern.
