Jekyll
Jekyll builds plain HTML, so there's nothing to run when a visitor presses Send. Point the form at BootForm and it is. Everything on this page works on GitHub Pages as it is, with no plugins and nothing to add to your Gemfile.
Basic form
Put the form straight into any page. HTML inside a Markdown file is passed through as it is:
---
layout: page
title: Contact
permalink: /contact/
---
<form action="https://f.bootform.com/{form_id}" method="POST">
<label for="email">Your email</label>
<input id="email" name="email" type="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" required></textarea>
<input type="text" name="_honeypot" style="position:absolute;left:-9999px" tabindex="-1" autocomplete="off">
<button type="submit">Send</button>
</form>Replace {form_id} with a UUID you generate yourself (the UUID generator gives you one). Send yourself a test message, then claim the form before the site goes live, so nobody else can claim your ID first.
The _honeypot field is a spam trap: people never see it, bots fill it in. Keep it positioned off screen as shown, not hidden with hidden or display:none, which some bots know to skip. See Spam protection.
Keep the form ID in _config.yml
If the form appears on more than one page, or you might change it, keep the ID in one place:
# _config.yml
bootform_form_id: "{form_id}"Then move the form into an include, _includes/contact-form.html, and read the ID from site:
<form action="https://f.bootform.com/{{ site.bootform_form_id }}" method="POST">
<label for="email">Your email</label>
<input id="email" name="email" type="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" required></textarea>
<input type="text" name="_honeypot" style="position:absolute;left:-9999px" tabindex="-1" autocomplete="off">
<button type="submit">Send</button>
</form>Use it on any page with:
{% include contact-form.html %}Keep that line at the start of a line in a Markdown file, with no indentation in front of it. Markdown treats a line indented by four spaces as a code block, so an indented include shows the start of your form's HTML as text and breaks the rest of the form.
jekyll serve only reads _config.yml when it starts. Restart it after you change the ID.
A thank-you page
By default, a successful submission sends the visitor back to the page the form was on. To send them to a page of your own instead, add a _redirect field with the full URL. Jekyll's absolute_url filter builds it from your _config.yml:
<input type="hidden" name="_redirect" value="{{ '/thanks/' | absolute_url }}">and create the page it points at, thanks.md:
---
layout: page
title: Thanks
permalink: /thanks/
---
Thanks, your message is on its way. We'll reply within a day.absolute_url uses url and baseurl from _config.yml, so set both. On GitHub Pages a project site (anything but yourname.github.io itself) is served from a subpath, and baseurl has to match it:
# _config.yml
url: "https://yourname.github.io"
baseurl: "/your-repo-name"Get baseurl wrong and the redirect lands on a 404, even though the form itself worked. On your own domain, set url to it and baseurl to "".
Sending without leaving the page
To submit in the background and show a message in place, add the script from the Vanilla JS guide's AJAX section to the page. It works unchanged in Jekyll: the same form, plus a <p id="status" role="status"></p> for the message. Leave _redirect out in that case; it only applies to a classic form post.
File uploads and the moderated feed
Both work on a Jekyll site exactly as in plain HTML: see Vanilla JS, file upload and Vanilla JS, moderated content feed. A file upload needs the form claimed first.
Common problems
The page shows part of the form's HTML as text, and the form is broken. The include or the form is indented in a Markdown file. Move it to the start of the line.
The built form's action ends in f.bootform.com/, with no ID. The include didn't find bootform_form_id. Restart jekyll serve, which doesn't reload _config.yml, and check the key is spelled the same in both files.
After sending, the visitor lands on a 404. The _redirect URL is wrong, almost always because baseurl doesn't match where the site is served. Open the built page's source and check the value of the _redirect field.
You sent a test message but no email arrived. The form isn't claimed yet. Nothing is delivered until it is; claim it and the messages sent so far are delivered. Held messages are kept for 48 hours.