Kontaktformular auf einer statischen Site6 Min. Lesezeit
Ein Kontaktformular in eine GitHub-Pages-Site einbauen
GitHub Pages kann keinen Servercode ausführen, also bekommt ein Formular-POST 405 Not Allowed; sende an ein Formular-Backend und setze Weiterleitungen für Projekt-Sites richtig.
GitHub Pages liefert nur statische Dateien aus, daher bekommt ein Formular, das an deine eigene Site sendet, 405 Not Allowed, und die Nachricht geht verloren. Setze die action des Formulars auf einen Ikiform-Endpunkt, füge username.github.io und eine eventuelle eigene Domain zu Allowed domains hinzu und leite auf eine Dankeseite weiter, die den Pfad deiner Projekt-Site enthält. In deinem Repository und deinen Pages-Einstellungen ändert sich nichts, und kein Geheimnis landet im öffentlichen Repo.
Was bei GitHub Pages anders ist
GitHub Pages veröffentlicht, was dein Repository oder dein Actions-Workflow baut, und sonst nichts. Jekyll läuft zur Build-Zeit, falls du es nutzt, danach ist das Ergebnis eine Sammlung von Dateien. Es gibt keinen Request-Handler, daher laufen PHPs mail(), ein Node-Skript oder ein Python-CGI-Formular nicht, egal was du committest.
Du kannst den Fehler im Terminal sehen. Ein POST an eine beliebige Seite einer Pages-Site bekommt das hier:
curl -i -X POST -d "message=hello" https://ada.github.io/notebook/contact.htmlHTTP/2 405
server: Varnish
content-length: 131
<html>
<head><title>405 Not Allowed</title></head>Vier weitere Dinge unterscheiden Pages von anderen statischen Hosts, und jedes betrifft das Kontaktformular:
| Pages-Eigenschaft | Was das für das Formular bedeutet |
|---|---|
Projekt-Sites liegen unter einem Pfad, username.github.io/repo/ | Eine Danke-URL /thanks.html zeigt auf die User-Site, nicht auf dein Projekt. Jede URL braucht den Teil /repo/ |
| Keine Einstellung für eigene Response-Header | Eine Content-Security-Policy kann nur aus einem <meta>-Tag in der Seite kommen |
| Das Repository ist oft öffentlich | Alles darin ist öffentlich. Die Formular-ID kann dort stehen; ein geheimer API-Schlüssel oder ein E-Mail-Passwort niemals |
| GitHub sagt, Pages-Sites sollten nicht für sensible Vorgänge wie das Senden von Passwörtern oder Kreditkartennummern genutzt werden | Lass das Kontaktformular ein Kontaktformular sein. Sammle darüber keine Kartendaten oder Kontopasswörter |
- Du pushst auf den Branch, aus dem Pages veröffentlicht.
- Jekyll oder dein Actions-Workflow baut die Site einmal.
- Pages liefert das Ergebnis als statische Dateien auf github.io oder deiner eigenen Domain aus.
- Ein Besucher sendet das Kontaktformular ab. Zeigt seine action auf deine eigene Site, antwortet Pages mit 405 Not Allowed.
- Ist die action auf deinen Ikiform-Endpunkt gesetzt, speichert Ikiform die Nachricht und schickt dir eine E-Mail.
- Ikiform leitet den Browser auf die Dankeseite weiter, die Pages wie jede andere Datei ausliefert.
Das Formular
Für eine handgeschriebene Site leg contact.html neben index.html. Diese hier ist für eine Projekt-Site unter ada.github.io/notebook, daher enthält die Weiterleitung /notebook/:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; form-action 'self' https://ikiform.com; connect-src 'self' https://ikiform.com"
/>
<title>Contact</title>
</head>
<body>
<h1>Get in touch</h1>
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<label for="name">Name</label>
<input id="name" name="name" autocomplete="name" required />
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="about">What is it about?</label>
<select id="about" name="about">
<option value="question">A question about the project</option>
<option value="hire">Work together</option>
<option value="other">Something else</option>
</select>
<label for="message">Message</label>
<textarea id="message" name="message" rows="6" minlength="10" required></textarea>
<input type="hidden" name="page" value="docs-home" />
<input type="hidden" name="_redirect" value="https://ada.github.io/notebook/thanks.html" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button type="submit">Send</button>
</form>
</body>
</html>- Die
<meta>-Content-Security-Policy ist optional. Behalte sie, wenn du eine hast, und sorg dafür, dassform-actionundconnect-srchttps://ikiform.comenthalten. Pages kann den Header nicht für dich senden. - Das Select
aboutsagt dir, warum jemand geschrieben hat, bevor du die Nachricht öffnest. Ändere die Optionen in das, worüber dir Leute tatsächlich schreiben. - Das versteckte Eingabefeld
pagehält fest, auf welcher Seite das Formular war, was nützlich ist, wenn dasselbe Formular auf mehreren Doku-Seiten steht. - Behalte
emailals Feldnamen. Benachrichtigungs-E-Mails nutzen es als Reply-To-Adresse.
Wenn dasselbe HTML unter mehreren Pfaden deployt wird oder du nicht sicher bist, wie der endgültige Pfad lautet, bau die Weiterleitung im Browser aus der eigenen Adresse der Seite. Setze das hinter das Formular:
<script>
document.querySelectorAll('input[name="_redirect"]').forEach((input) => {
input.value = new URL("thanks.html", document.baseURI).href;
});
</script>Du nutzt Jekyll? Schreib die URL gar nicht fest hinein. Die Jekyll-Anleitung hat ein Include, das sie mit absolute_url baut, was für Projekt-Sites deine baseurl ergänzt. Du baust mit Astro, Vite oder Hugo über einen Actions-Workflow? Setze den Basispfad des Frameworks auf /repo/, damit die Assets des Formulars laden, und nutze für das Formular selbst die Anleitung zu Hugo oder zu deinem Framework.
Erlaubte Domains auf github.io
Füge ada.github.io mit deinem eigenen Benutzernamen hinzu. Das deckt deine User-Site und jede Projekt-Site ab, weil Projekt-Sites denselben Host teilen. Füge auch deine eigene Domain hinzu, falls du eine nutzt; example.com deckt auch www.example.com ab.
Füge niemals github.io allein hinzu. Jede Pages-Site würde passen, auch Kopien deines Formulars auf den Sites anderer Leute. Mit gesetzten erlaubten Domains wird einem _redirect auf https://ada.github.io/notebook/thanks.html gefolgt; ohne sie ignoriert Ikiform ihn und zeigt seine gehostete Dankeseite.
_redirect-Werten, die mit https: beginnen, und eine eigene Domain ohne Zertifikat liefert vorerst http:-Seiten aus.Einen mailto:-Link ersetzen
Viele Pages-Sites beginnen mit einem mailto:-Link im Footer. Ersetzt du ihn durch das Formular, können neue Scraper deine Adresse nicht mehr von der Seite lesen, und Besucher ohne eingerichtete Mail-App erreichen dich endlich. Zwei Dinge solltest du wissen, bevor du ihn löschst:
- Die Adresse bleibt in der Historie deines Repositorys und in jedem Fork oder Archiv der alten Seite. Das Formular hilft ab jetzt; es macht eine Adresse, die jahrelang öffentlich war, nicht wieder privat.
- Antworten kommen aus deinem eigenen Postfach. Benachrichtigungs-E-Mails setzen den Absender als Reply-To-Adresse, daher funktioniert Reply so wie vorher der
mailto:-Link, nur von der anderen Seite.
Ikiform schickt dem Besucher nie eine E-Mail, also schreib auf die Dankeseite, wann er mit einer Antwort rechnen kann. Wenn du mehr Nachrichten bekommst, als du per E-Mail beantworten kannst, kann ein Webhook jede davon stattdessen in Slack oder Discord ablegen.
Prüfen, ob es funktioniert
Führe das auf der Live-Adresse unter github.io aus. Pages hat keine Preview-Deployments, also teste zuerst lokal mit einem lokalen Server.
- Füge
localhostundusername.github.iounter Allowed domains hinzu, plus deine eigene Domain, falls du eine hast. - Committe
contact.htmlundthanks.html, warte im Tab Actions des Repositorys, bis das Pages-Deployment fertig ist, und öffne die Live-Seite. - Sende das Formular ab. Du solltest auf deiner eigenen
thanks.htmllanden, mit dem Projektpfad in der Adresszeile. - Öffne Submissions im Dashboard. Die neue Einsendung ist da, mit jedem Feld, das du gesendet hast.
- 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. - Nichts angekommen? Stell den Statusfilter im Dashboard auf Spam. Spam bekommt dieselbe Erfolgsantwort wie eine echte Einsendung.
Stolperfallen
| Problem | Was zu tun ist |
|---|---|
405 Not Allowed nach dem Klick auf Senden | Das deployte Formular sendet noch an deine eigene Site. Sieh dir den Quelltext der Seite auf github.io an und prüfe die action; ein alter gecachter Build kann noch ein paar Minuten live sein. |
| Die Dankeseite von Ikiform statt deiner | Dem _redirect-Wert fehlt der Repository-Pfad, er ist http:, oder das Formular hat keine erlaubten Domains. Füge username.github.io hinzu und nutze die vollständige https:-URL. |
403 origin_not_allowed, oder jeder Post landet im Spam | Die Domain der Seite steht nicht unter Allowed domains des Formulars. Füge sie hinzu, plus localhost für lokale Tests. Subdomains einer eingetragenen Domain sind erlaubt. |
| Formular-Posts funktionieren lokal, aber die Konsole zeigt auf github.io einen CSP-Fehler | Einer <meta>-Content-Security-Policy in deinem Layout fehlt https://ikiform.com in form-action oder connect-src. |
Fragen
Nein. GitHub Pages liefert statische Dateien aus und führt keinen Code aus, wenn ein Besucher ein Formular absendet, daher bekommt ein POST an eine Pages-URL 405 Not Allowed. Richte die action des Formulars stattdessen auf ein Formular-Backend aus.
Ja. Die Formular-ID landet ohnehin in deinem öffentlichen HTML. Schütze das Formular mit erlaubten Domains und den Spamprüfungen und committe niemals einen geheimen API-Schlüssel, weil eine statische Site keinen sicheren Ort dafür hat.
Ein Pfad wie /thanks.html zeigt auf die Wurzel von username.github.io, nicht auf dein Projekt. Nutze die vollständige URL mit dem Repository-Pfad oder bau sie im Browser aus document.baseURI.
Ja. Das Formular sendet an Ikiform, egal welche Domain die Seite ausliefert. Füge die eigene Domain unter Allowed domains neben username.github.io hinzu und stell jeden _redirect-Wert auf die eigene Domain um, sobald HTTPS erzwungen wird.
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.
Hängst du bei einem Schritt fest oder willst eine Anleitung für deinen Fall? Schreib an hello@ikiform.com.