Guide Thumbnail
+

HTML Forms with Jekyll

In this guide we’ll show you how to add a contact form to your Jekyll website using Formspree.

Formspree is a form backend that’s an ideal companion for static site generators, letting you get on with building and deploying your Jamstack website.

At the end of this guide you should have a working HTML contact form in your Jekyll project that sends you email notifications. Check out a live demo of the final project. The project repository is hosted on GitHub.

Prerequisites

To follow this guide you’re going to need a Formspree account, which you can sign up for free right here, and an existing website built in Jekyll. If you don’t have a Jekyll project yet, you can create one by running:

jekyll new my-awesome-site

If you’re not familiar with Jekyll, then check out the official website to learn more.

Adding a form to Jekyll

Jekyll uses Liquid as it’s templating language meaning that the form code you’re about to add can be neatly wrapped up in a partial. Create a new file called contact-form.html inside of your _includes directory within the source of your Jekyll project. Here’s an example of the file structure including your new partial:

project-root/
├─ config.yml
├─ _includes/
|  └─ contact-form.html
└─ index.html

Now you can copy-paste the following example form into your contact-form.html partial and tailor it to meet your needs:

<form action="https://formspree.io/f/YOUR_FORM_ID" method="POST">

  <label>
    Your email:
    <input type="email" name="email">
  </label>

  <label>
    Your message:
    <textarea name="message"></textarea>
  </label>

  <button type="submit">Send</button>
</form>

A few notes:

  • Currently the action attribute contains a placeholder YOUR_FORM_ID. We’ll replace this with our own form endpoint in a bit.
  • The method attribute must be POST for the form to submit correctly.
  • Each input has a name attribute. This is essential to correctly send the data to Formspree.
  • For the sake of clarity, this form doesn’t include any styling, but you can see an example of how to apply styles to the form in this tutorial’s companion GitHub project.
  • You can create any form you want by adding your own <input ... > tags and labels. For more examples and inspiration checkout our Form Library.

The partial code can then be included in any one of your markdown or liquid template files. Open a template file that you wish to add a form and add the following code:

{% include contact-form.html %}

Once you’ve saved your changes, use your build or deployment workflow to either run the Jekyll site locally or deploy it to your live environment to see the newly added form.

When you attempt to submit the new form you’ll see a page like this:

HTML form submit error

Oops! Thats because we still have the placeholder YOUR_FORM_ID in the form action. Let’s fix this by setting up a form endpoint to accept our form submissions.

Creating a form endpoint

Next we’ll create a form endpoint using Formspree. If you don’t have an account yet you can sign up.

To start, create a new form with the +New form button, call it Contact form and update the recipient email to the email where you wish to receive your form submissions. Then click Create Form.

Formspree new form modal

You’ll then be presented with the integration options for your new Formspree form. Formspree provides you with a wide range of implementation examples such as React, Ajax and regular HTML.

HTML form integration code

Integration view of the sample code section, tabbed with alternative language samples

The code we used to create the contact-form.html partial is almost identical to the HTML example code on the integration page. We just need to update the action URL.

Copy the 8 character ID from your new form’s endpoint URL and replace the YOUR_FORM_ID placeholder in your contact-form.html partial.

<form action="https://formspree.io/f/abcd1234" method="POST">

Now when you fill out the form and submit, you should see a success message.

That’s it, you’re done!

Bonus Tip: Production and Development Forms

Sometimes you want to test out a new design locally, but don’t want to affect your production data. With Jekyll you can switch between development and production forms using the jekyll.environment variable.

Using liquid, you can replace your form endpoint with a conditional like so:

{% if jekyll.environment == "production" %}
<form action="https://formspree.io/f/PROD_FORM_ID" method="POST">
{% else %}
<form action="https://formspree.io/f/DEV_FORM_ID" method="POST">
{% endif %}
  ...
</form>

Replace the placeholders PROD_FORM_ID and DEV_FORM_ID above with the hashids for your production and development forms, respectively.

As you’re developing locally your environment will be set to development by default. Then, depending on where you deploy, you may need to set the JEKYLL_ENV environment variable to production, which will switch the form endpoint to the production form. (Github Pages automatically sets the JEKYLL_ENV variable to production)

You can read more about how to set the environment in Jekyll, and how to set build environment variables in Netlify or Vercel.


Got Feedback?