Jekyll contact form
Jekyll builds the page and the browser posts it, so there is no plugin to install and nothing to run on the server. The form is an include, and the two values it needs live in _config.yml.
Create the form in the console first. It gives you a form ID for the URL and the name of a honeypot field for your markup. Both are rendered into the page, and neither is a secret.
The include
<form action="https://api.ezform.io/f/{{ site.ezform.form_id }}" method="POST">
<label for="email">Email</label>
<input id="email" name="email" type="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" required></textarea>
<div style="position:absolute;left:-9999px" aria-hidden="true">
<label for="{{ site.ezform.honeypot }}">Company website</label>
<input
id="{{ site.ezform.honeypot }}"
name="{{ site.ezform.honeypot }}"
type="text"
tabindex="-1"
autocomplete="off">
</div>
<button type="submit">Send</button>
</form>
ezform:
form_id: YOUR_FORM_ID
honeypot: YOUR_HONEYPOT_FIELD
jekyll serve watches your content but not _config.yml. After adding those two keys, stop the
server and start it again, or the form renders with an empty ID and posts into nothing.
Using it in a page
---
layout: page
title: Contact
---
Tell us what you need and we will get back to you.
{% include ezform-form.html %}
The front matter at the top is not decoration. A file without it is copied to the output untouched, Liquid and all, so the include tag ends up in the page as literal text and no form is rendered. If the form is missing and the page otherwise looks right, that is the first thing to check.
Allow your origins
Scheme and host, no path, one entry each:
http://localhost:4000forjekyll serve, if you test against the real endpoint rather than filling the console in by hand.- Your production host. The apex and
www.are two different origins.
On GitHub Pages the origin is the host alone, so a project site published at https://you.github.io/project is served from the origin https://you.github.io. Allowlist that, with no path, and it covers every project site on the same account. A custom domain is its own origin and needs its own entry.
A submission from an origin that is not listed is discarded and never stored, which is what keeps someone who read your form ID out of your inbox. It is also the first thing to check when a form appears to do nothing: see Responses and failure.
What happens when someone submits
The browser posts the form and navigates. Configure a redirect path on the form in the console and ezform answers 303 to that page, so a refresh cannot repost the submission. Without one, ezform renders its own short confirmation page.
The site ships no JavaScript for any of this, so the form still works with JavaScript turned off.
Where to go next
- Quickstart for the two values you need from the console
- Spam and origins for why the honeypot is hidden off-screen rather than with
display: none - Submitting a form for the field limits and the encodings accepted