Next.js-Kontaktformular ohne API-Route
In Next.js brauchst du keine API-Route und keinen Mail-Anbieter. Eine Client-Komponente sendet direkt an Mailiy. Das funktioniert im App Router und im Pages Router, auch bei statischem Export.
So baust du es ein
- Leg ein kostenloses Konto an, füg deine Website hinzu und kopier den Schlüssel des Formulars.
- Leg die Datei unten an und ersetz YOUR_ACCESS_KEY.
- Importier sie in app/contact/page.jsx und rendere <ContactForm />.
- Deploy wie gewohnt, etwa auf Vercel oder als statischen Export.
app/contact/ContactForm.jsx
"use client";
import { useState } from "react";
export default function ContactForm() {
const [status, setStatus] = useState("");
const onSubmit = async (event) => {
event.preventDefault();
const data = Object.fromEntries(new FormData(event.currentTarget));
const res = await fetch("https://mailiy.com/api/submit", {
method: "POST",
headers: { "content-type": "application/json", accept: "application/json" },
body: JSON.stringify({ ...data, access_key: "YOUR_ACCESS_KEY" }),
});
const result = await res.json();
setStatus(result.success ? "Danke!" : result.message);
};
return (
<form onSubmit={onSubmit}>
<input type="email" name="email" required />
<textarea name="message" required />
<input type="checkbox" name="botcheck" style={{ display: "none" }} />
<button>Senden</button>
<p role="status">{status}</p>
</form>
);
}Was du bei Next.js wissen solltest
- Ohne "use client" am Anfang meldet der App Router einen Fehler, weil die Komponente useState nutzt.
- Der Schlüssel darf im Client-Code stehen. Eine Umgebungsvariable mit NEXT_PUBLIC_ geht auch, schützt ihn aber nicht zusätzlich.
Felder, die Mailiy erkennt
Jedes Feld mit Namen erscheint in der E-Mail und im Dashboard. Einige Namen liest Mailiy selbst und steuert damit, wie die Mail aussieht und was danach passiert:
| Name | Wirkung |
|---|---|
subject | Betreff der E-Mail. Ohne das Feld nimmt Mailiy den Betreff aus den Formular-Einstellungen. |
from_name | Absendername, der im Postfach angezeigt wird, etwa der Name deiner Website. |
email / replyto | Adresse der Person, die das Formular ausfüllt. Mit „Antworten“ schreibst du ihr direkt zurück. |
redirect | Adresse, auf die der Browser nach dem Absenden geht, zum Beispiel deine eigene Danke-Seite. |
ccemail / bccemail | Weitere Empfänger in Cc oder Bcc, getrennt mit Semikolon. Es zählen nur Adressen, die in deinem Konto bestätigt sind. |
consent | Checkbox für die Einwilligung. Verlangst du sie im Dashboard, lehnt Mailiy Einsendungen ohne Haken ab. |
botcheck | Unsichtbare Falle für Bots. Bleibt sie leer, ist alles in Ordnung. |
Dateien mitschicken
Mit einem Feld vom Typ file nimmt dein Formular in Next.js auch Anhänge an, bis zu fünf Dateien mit zusammen 10 MB. Erlaubt sind PDF, Bilder, Text- und Office-Dateien. Mailiy prüft bei jeder Datei, ob der Inhalt zur Endung passt, und lehnt alles andere ab.
Die Komponente oben schickt JSON, und darin haben Dateien keinen Platz. Für Uploads übergibst du fetch() direkt das FormData-Objekt als body und lässt den Header Content-Type weg, den setzt der Browser dann selbst.
Wenn keine E-Mail ankommt
Mailiy antwortet auf jede Einsendung mit einer Meldung. Meistens steckt eine dieser Ursachen dahinter:
- Falscher Schlüssel. Die Antwort lautet „Invalid access key“. Kopier den Schlüssel noch einmal aus dem Dashboard, ohne Leerzeichen davor oder danach.
- Domain nicht erlaubt. Hast du im Dashboard erlaubte Domains eingetragen, nimmt Mailiy nur Einsendungen von dort an. Subdomains zählen mit. Zum Testen auf einer Vorschau-Adresse trägst du diese vorübergehend dazu.
- Feld ohne Namen. Ein Eingabefeld ohne name-Attribut schickt der Browser gar nicht mit. Es fehlt dann in der E-Mail, ohne dass eine Fehlermeldung erscheint.
- Zu viele Tests hintereinander. Pro Formular und Besucher nimmt Mailiy fünf Einsendungen in der Minute an. Danach kommt „Too many submissions“, und nach kurzer Pause geht es weiter.
- Mail im Spam-Ordner. Schau zuerst in den Spam-Ordner und markier die erste Mail als „Kein Spam“. Steht die Einsendung im Dashboard, hat Mailiy sie angenommen.
- Neuer Empfänger bekommt nichts. Weitere Empfänger bekommen erst Mails, wenn sie ihre Adresse über den Link in der Bestätigungsmail freigegeben haben.
Nach dem Absenden
Jede Einsendung landet im Dashboard. Dort durchsuchst du sie und exportierst sie als CSV. Im Formular stellst du außerdem eine automatische Antwort ein, die an die Adresse aus dem Feld email geht, etwa „Danke, wir melden uns innerhalb von zwei Tagen“.
Soll dein Team die Nachricht auch im Chat sehen, schickt Mailiy sie zusätzlich an Slack, Discord oder Telegram. Für eigene Abläufe gibt es Webhooks, die jede Einsendung als JSON an eine Adresse deiner Wahl senden.
Spam und Datenschutz
Das unsichtbare Feld botcheck ist eine Falle für Bots. Kreuzen sie es an, verwirft Mailiy die Einsendung, ohne sie zu speichern oder zu verschicken. Weitere Filter und ein Captcha schaltest du im Dashboard dazu.
Mailiy läuft auf Servern in Deutschland und setzt keine Tracker. Was du sonst noch für ein DSGVO-konformes Formular brauchst, steht in der DSGVO-Checkliste.
Häufige Fragen
Kann ich stattdessen eine Server Action nehmen?
Das geht, bringt aber keinen Vorteil. Eine Anfrage vom Server schickt keinen Origin-Header mit. Hast du im Dashboard erlaubte Domains eingetragen, lehnt Mailiy sie deshalb ab. Die Client-Komponente ist einfacher.
Brauche ich für das Kontaktformular in Next.js einen eigenen Server?
Nein. Das Formular sendet an Mailiy, Mailiy verschickt die E-Mail. Du brauchst weder PHP noch SMTP-Zugangsdaten noch Server-Code.
Darf der Schlüssel im Quelltext der Seite stehen?
Ja. Er erlaubt nur, Einsendungen an dieses eine Formular zu schicken. Er gibt keinen Zugriff auf dein Konto. Im Dashboard legst du fest, von welchen Domains Einsendungen angenommen werden.
Was kostet das?
Der kostenlose Tarif enthält 100 Einsendungen im Monat für eine Website. Bezahlte Tarife beginnen bei 9 € im Monat.