Developer docs

How to add a contact form to a Ghost site

A contact form on your site is a way for your audience to get in touch with you directly. In this tutorial we’ll show you how to add a custom contact form directly into your Ghost theme.

Prerequisites

The following tutorial involves customising a Ghost theme, specifically Casper theme. To learn more check out our extensive Handlebars theme documentation as well as our FAQ guides on downloading and uploading themes. If you’re looking for a less code-heavy way of adding a contact form to your Ghost site then check out our form Integrations. You’ll also need to sign up to Formspree, which is the service we’ll be using for handling form submissions.

Creating a custom page template

This tutorial covers how to add a contact form to a page with custom styling. To provide more control of where the form can be added, we’re going to take this one step further by creating a custom page template. This means all authors of your site will be able to add a form to any page using a single drop-down menu.

Create a new template file

Create a new file at the root of your theme called custom-page-with-form.hbs and open it in your code editor. To get a head start on the template, and to match the existing page template design, open the existing page.hbs template and copy the code within it into the new custom template file you just created.

Creating a form

For this tutorial we’re going to be using Formspree, a service designed to add forms to any web page using standard HTML.

Locate a position in your recently created template where you would like a form to be rendered. In my example I’ve placed the form just after the main content within the page. Using the Formspree documentation as guidance, add a HTML form to the custom-page-with-form.hbs template.

<section class="post-full-content">
    <div class="post-content">
        {{content}}
    </div>

    <form class="contact-form" action="https://formspree.io/YOUR@EMAIL.HERE" method="post">
        <label for="full-name">Name</label>
        <input type="text" name="name" id="full-name" placeholder="First and Last" required>
        <label for="email-address">Email Address</label>
        <input type="email" name="_replyto" id="email-address" placeholder="Your email address" required>
        <label for="message">Message</label>
        <textarea rows="5" name="message" id="message" placeholder="Your message" required></textarea>
        <input type="hidden" name="_subject" id="email-subject" value="Contact Form Submission">
        <input type="submit" value="Submit">
    </form>

</section>

Any message sent using this form will get sent directly to your email inbox. You’ll need to update the form action value with your email. The form above includes Name, Email and Message fields. However if you’re wanting something more custom to your needs, check out the examples in the Formspree Library, or their official documentation.

Styling your contact form

Next we need to add some style and layout to our form. Depending on your theme, you might already have some default styles for form elements. If you’re using Casper, like in this tutorial, the following CSS should get you off to a good start:

.contact-form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-gap: 0.2em 1em;
}
.contact-form input,
.contact-form textarea {
    width: 100%;
    border: none;
    padding: 0.4em 0.6em 0.5em;
    color: #111;
    font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Open Sans, Helvetica Neue, sans-serif;
    font-size: 0.95em;
}
.contact-form input:focus,
.contact-form textarea:focus {
    outline: 1px solid #3eb0ef;
    outline-offset: -1px;
}
.contact-form label[for="full-name"],
.contact-form label[for="email-address"] {
    order: -1;
}
.contact-form input {
    order: 0;
    margin-bottom: 0.6em;
}
.contact-form label[for="message"],
.contact-form textarea {
    grid-column-end: span 2;
}
.contact-form input[type="submit"] {
    grid-column-start: 2;
    justify-self: end;
    margin-top: 0.6em;
    background: #3eb0ef;
    color: white;
    width: auto;
}

The above styles will produce a layout like this:

Testing your contact form

The final step is to test out your form. Save your theme changes and upload the theme via the Design settings area in Ghost admin. Next, create a new page called “Contact” and use the Template select option at the bottom of the page settings to select the template “Page With Form”.

Custom template drop-down

Hit publish and navigate to the page on your site to see the form in action.

Formspree requires you to make an initial form submission to activate the form, this prevents unwanted spam. Fill in your form and follow the steps after submitting. After the setup is complete you’ll be able to make a real form submission, which will arrive in your email inbox and look something like this:

Example of a message arriving in your email inbox

Congrats on receiving your first contact form submission 🎉

Improving user experience

You may have noticed after submitting your form that the thank you message is from Formspree and not very in keeping with your site.

Default thank you page from Formspree

Formspree provides the option to add your own custom thank you page by adding a hidden input element into your form. Here’s an example:

<input type="hidden" name="_next" value="{{@site.url}}/thanks/" />

The value of the hidden input needs to be an existing page on your site. In the example above a “Thanks” page has been created which has a thank you message for anyone who uses the form. Check out the official Formspree documentation for other ways to enhance the user experience.

Summary

Well done! Not only have you added a contact form to your site, which will allow you to make direct contact with your audience, but you’ve also used custom templates that can be optionally set using page settings within your Ghost admin. Many people in the Ghost community share their advanced knowledge with others in the official Ghost community forum, why don’t you come say hey 👋