Anleitung
Next.js-Kontaktformular (kein Backend nötig)
Next.js braucht keinen eigenen Formular-Empfänger. Sie können dasselbe einfache HTML-Formular-Action in jede Server-Komponente einfügen, oder - wenn Sie clientseitige Erfolgs- und Fehlerzustände wollen - eine kleine Client-Komponente mit fetch verwenden. Beide POSTen direkt an Formhook.
Verwenden Sie ein einfaches HTML-Formular
Sie benötigen keine API-Route. Das Formular sendet direkt an Formhook, und Ihr Framework muss die Einsendung nie selbst verarbeiten.
<form action="https://formhook.app/f/YOUR_API_KEY" method="POST">
<label>
Email
<input type="email" name="email" required />
</label>
<label>
Message
<textarea name="message" required></textarea>
</label>
<!-- honeypot: bots fill this; humans don't see it -->
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off" hidden />
<!-- optional: send users to a thank-you page after a native POST -->
<input type="hidden" name="_redirect" value="https://example.com/thanks" />
<button type="submit">Send</button>
</form>Oder mit fetch in Next.js senden
Verwenden Sie diese Variante, wenn Sie client-seitige Erfolgs-/Fehlerzustände ohne vollständigen Seiten-Reload möchten.
"use client";
import { useState } from "react";
export function ContactForm() {
const [status, setStatus] = useState<"idle" | "sending" | "ok" | "error">("idle");
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setStatus("sending");
const form = e.currentTarget;
const data = Object.fromEntries(new FormData(form));
const res = await fetch("https://formhook.app/f/YOUR_API_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
setStatus(res.ok ? "ok" : "error");
if (res.ok) form.reset();
}
if (status === "ok") return <p>Thanks - we'll be in touch.</p>;
return (
<form onSubmit={onSubmit}>
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" required />
<input type="text" name="_gotcha" tabIndex={-1} hidden />
<button type="submit" disabled={status === "sending"}>
{status === "sending" ? "Sending…" : "Send"}
</button>
{status === "error" && <p>Something went wrong. Please try again.</p>}
</form>
);
}So funktioniert es
Das einfache Formular-Action funktioniert in jeder Next.js-Seite oder jedem Layout, einschließlich Server-Komponenten. Kein app/api/contact/route.ts, keine Server Action, keine Middleware. Wenn Sie eine clientseitige UX mit Erfolgs- und Fehlerzuständen wollen, zeigt das zweite Snippet das kanonische Muster: "use client", useState, onSubmit, fetch an formhook.app/f/YOUR_API_KEY. Das Honeypot-Feld (_gotcha) und optional _redirect sind dieselben Sonderfelder aus der HTML-Anleitung.
Normales Formular oder fetch: was sollten Sie nehmen?
Nehmen Sie das normale action-Formular, wenn Sie ganz ohne JavaScript auskommen wollen: Es funktioniert in einer Server Component und läuft weiter, auch wenn die Hydration fehlschlägt. Der Preis: Der Browser verlässt beim Absenden Ihre Seite. Fügen Sie deshalb ein verstecktes _redirect-Feld mit einer absoluten URL einer Ihrer erlaubten Origins hinzu, etwa https://example.com/danke. Ohne dieses Feld sehen Besucher eine rohe JSON-Antwort.
Nehmen Sie die fetch-Variante, wenn Erfolgs- oder Fehlermeldung direkt auf der Seite erscheinen sollen, mit deaktiviertem Button während des Sendens. Klassische Formular-Posts können weiterleiten; JSON-fetch-Posts erhalten eine JSON-Antwort, daher wird _redirect dort ignoriert. Mehr dazu in AJAX-Formularübermittlung.
403 origin_not_allowed in der lokalen Entwicklung beheben
Formhook akzeptiert Browser-Einsendungen nur von Origins, die Sie unter Erlaubte Origins Ihres Formulars eingetragen haben - und der Abgleich ist exakt: Schema, Host und Port. http://localhost:3000, https://example.com und https://www.example.com sind drei verschiedene Origins. Tragen Sie Ihre Entwicklungs-URL, Ihre Produktionsdomain und jede Preview-Domain ein, auf der Sie testen - ohne Pfad und ohne abschließenden Schrägstrich. Bei einer leeren Liste werden alle Browser-Anfragen abgelehnt.
Schlägt eine Einsendung trotzdem fehl, nennt der Antwort-Body den Grund: origin_not_allowed (403) heißt, die Origin fehlt in der Liste, form_not_found (404) heißt, der API-Schlüssel stimmt nicht, und rate_limited (429) heißt, die unter Retry-After genannten Sekunden abzuwarten. Mehr in Kontaktformular funktioniert nicht?
Wohin mit dem API-Schlüssel?
Der Schlüssel landet so oder so in Ihrem HTML oder JavaScript-Bundle - behandeln Sie ihn also als öffentliche Kennung, nicht als Geheimnis. Eine Umgebungsvariable NEXT_PUBLIC_FORMHOOK_KEY ist trotzdem praktisch, um in der Entwicklung ein anderes Formular zu nutzen als in Produktion.
Geschützt wird das Formular auf Seiten von Formhook: durch die Liste erlaubter Origins, das _gotcha-Honeypot, Rate Limits pro IP und pro Formular sowie optional Cloudflare Turnstile. Die Origin-Liste hindert andere Websites daran, aus dem Browser zu posten, ist aber keine Authentifizierung, denn ein Skript kann beliebige Origin-Header senden. Verlassen Sie sich bei Bots auf die Spam-Schichten; Spamschutz für Kontaktformulare vergleicht sie.
Stattdessen aus einer Server Action senden
Wenn Sie serverseitig Daten ergänzen oder vor dem Senden prüfen möchten, rufen Sie Formhook aus einer Server Action oder einem Route Handler auf. Serveranfragen senden keinen Origin-Header und müssen deshalb einen X-Auth-Token-Header mitschicken, den Sie in den Einstellungen Ihres Formulars erzeugen. Halten Sie dieses Token in einer reinen Server-Umgebungsvariable, niemals in einer Client Component. Die meisten Kontaktformulare brauchen das nicht - deshalb verzichten die Snippets oben darauf. Das vollständige Anfrageformat steht in der Dokumentation.
Bevor Sie live gehen
- Tragen Sie die Produktions-Origin mit
https://bei den erlaubten Origins ein. - Behalten Sie das
_gotcha-Honeypot-Feld und entscheiden Sie, ob Sie Turnstile aktivieren. - Senden Sie eine Testeinsendung und prüfen Sie, dass sie im Dashboard und als Push-Benachrichtigung ankommt.
- Ergänzen Sie unter dem Formular einen kurzen Datenschutzhinweis. Der Leitfaden zum DSGVO-konformen Kontaktformular enthält Formulierungen zum Anpassen.
Was als Nächstes passiert
- Einsendung erscheint innerhalb einer Sekunde in Ihrem Formhook-Dashboard.
- Push-Benachrichtigung wird auf allen aktivierten Geräten ausgelöst.
- Antworten Sie direkt aus dem Dashboard (Pro und höher) - praktisch für Kundenarbeit, bei der jedes Projekt seine eigene Kontakt-Route hat.
Veröffentlichen Sie heute Ihr Next.js-Kontaktformular.
Kostenlos registrieren, Formular erstellen, API-Schlüssel einfügen. Fünf Minuten.
Kostenlos startenKostenlose Stufe: 5 Formulare · 250 Einsendungen/Monat · Keine Kreditkarte.
Next.js-Kontaktformular - FAQ
Muss ich eine API-Route oder eine Server Action hinzufügen?
Kann ich das in einer Server-Komponente verwenden?
Wie behandle ich Spam, ohne Rate-Limit-Middleware zu schreiben?
Anleitungen für andere Frameworks
Migrating from Formspree? See how Formhook compares.