Gatsby
Ein Gatsby-Formular, das schon im statischen HTML vor der Hydration funktioniert, danach mit fetch erweitert wird, plus eine Gatsby Function für Posts mit einem geheimen Schlüssel.
Gatsby rendert jede Seite beim Build zu HTML. Gib dem Formular eine echte action, dann sendet es, bevor React hydriert oder falls das Bundle nicht lädt; nach der Hydration sendet die Komponente per fetch und zeigt das Ergebnis direkt an.
Aus dem Browser senden
Füge die Formular-ID hinzu
.env.production GATSBY_IKIFORM_FORM_ID=frm_xxxxxxxxxxxxxxxxGatsby gibt nur Variablen, die mit
GATSBY_beginnen, an Browser-Code weiter und fügt sie beim Build inline ein. Füge dieselbe Zeile fürgatsby developzu.env.developmenthinzu.Füge die Komponente hinzu
src/components/contact-form.js import * as React from "react"; const endpoint = `https://ikiform.com/f/${process.env.GATSBY_IKIFORM_FORM_ID}`; export default function ContactForm() { const [status, setStatus] = React.useState("idle"); const [message, setMessage] = React.useState(""); async function onSubmit(event) { event.preventDefault(); setStatus("sending"); 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 setStatus("sent"); setMessage(result.error.message); } catch { setMessage("Couldn't reach the server. Try again."); } setStatus("error"); } if (status === "sent") return <p>Thanks, we got it.</p>; return ( <form action={endpoint} method="post" onSubmit={onSubmit}> <label> Email <input name="email" type="email" autoComplete="email" required /> </label> <label> Message <textarea name="message" rows={5} /> </label> <input type="hidden" name="_redirect" value="https://example.com/thanks/" /> <input name="_gotcha" type="text" tabIndex={-1} autoComplete="off" hidden /> {status === "error" ? <p role="alert">{message}</p> : null} <button disabled={status === "sending"}>Send</button> </form> ); }Rendere sie auf einer beliebigen Seite, zum Beispiel
src/pages/contact.js, und fügesrc/pages/thanks.jsfür die Weiterleitung ohne JavaScript hinzu. Für Feldfehler und die Menschlichkeitsprüfung des SDK erweitere sie wie im React-Guide.
Aus einer Gatsby Function senden
Eine Gatsby Function kann den Post mit einem geheimen Schlüssel weiterleiten, der die erlaubten Domains und die Menschlichkeitsprüfung überspringt. Sie läuft nur auf Hosts, die Gatsby Functions unterstützen, etwa Netlify mit dem Gatsby-Adapter; ein rein statischer Host wie GitHub Pages kann sie nicht ausführen. Speichere IKIFORM_FORM_ID und einen geheimen Schlüssel mit dem Scope submissions:write als IKIFORM_SECRET_KEY, ohne das Präfix GATSBY_, damit sie nie den Browser erreichen.
export default async function handler(req, res) {
if (req.method !== "POST") return res.status(405).end();
const response = await fetch(`https://ikiform.com/f/${process.env.IKIFORM_FORM_ID}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${process.env.IKIFORM_SECRET_KEY}`,
},
body: JSON.stringify(req.body),
});
res.status(response.status).json(await response.json());
}Gatsby parst JSON- und form-encoded Bodies in req.body, daher kann die Seite auf beide Arten an /api/contact senden. Alle Posts teilen sich dann für Rate-Limits die IP-Adresse deiner Function; siehe Von einem Server.
Erlaubte Domains
Das gilt für Posts aus dem Browser. Posts aus der Gatsby Function nutzen einen geheimen Schlüssel und überspringen die Prüfung.
| Wo das Formular läuft | Zu Allowed domains hinzufügen |
|---|---|
gatsby develop und gatsby serve | localhost. Passt auf http://localhost:8000 und http://localhost:9000: Ikiform vergleicht nur den Hostnamen, nie den Port. |
| Deine Domain | example.com, was auch www.example.com abdeckt |
| Netlify | your-site.netlify.app. Deploy Previews (deploy-preview-12--your-site.netlify.app) und Branch Deploys (branch--your-site.netlify.app) sind keine Subdomains davon, füge also den exakten Preview-Host hinzu, während du eine testest. |
| Cloudflare Pages | your-project.pages.dev. Preview-URLs wie abc123.your-project.pages.dev sind Subdomains davon und passen daher bereits. |
- Füge niemals
netlify.appoderpages.devallein hinzu. Jede Site auf diesem Host würde passen, auch die von anderen Leuten.
Test-Checkliste
- Starte
gatsby buildund öffnepublic/contact/index.html. Dieactiondes Formulars sollte mit deiner Formular-ID enden, nicht mitundefined. - Starte
gatsby servemitlocalhostin den erlaubten Domains und sende ab. Die Dankesnachricht sollte das Formular ersetzen. - Schalte JavaScript aus, lade neu und sende ab. Lokal solltest du die Dankesseite von Ikiform sehen, auf deiner
https:-Domain/thanks/. - Wenn du die Function nutzt, sende in einer Deploy-Preview an
/api/contactund prüfe, dass die Einsendung in Ikiform erscheint.
Fehlerbehebung
| Was du siehst | Warum | Lösung |
|---|---|---|
404 not_found, und die action endet auf /f/undefined | Die Variable hat nicht das Präfix GATSBY_ oder war beim Build nicht gesetzt | Nenne sie GATSBY_IKIFORM_FORM_ID und baue neu. |
Die Function antwortet mit 403 forbidden | Der geheime Schlüssel stammt aus einem anderen Workspace, wurde widerrufen oder hat kein submissions:write | Erstelle einen geheimen Schlüssel mit diesem Scope. |
/api/contact gibt nach dem Deploy 404 zurück | Der Host liefert nur statische Dateien aus | Deploye auf einen Host mit Gatsby Functions oder nutze die Browser-Version. |
Einsendungen landen im Spamfilter mit origin_mismatch | Die sendende Seite steht nicht in den erlaubten Domains des Formulars | Füge den Host aus der Tabelle oben hinzu. Mit Reject bekommen dieselben Requests stattdessen 403 origin_not_allowed. |