Skip to content
Framework guide

Add a contact form to an Eleventy site

Eleventy outputs static HTML, so a contact form posts to Formwire rather than to your site. This guide puts the form in a Nunjucks include and a contact page that uses it.

4 min read

The form

Replace YOUR-ACCESS-KEY with the key from your form's page. The highlighted line is the one that points the form at Formwire.

src/_includes/contact-form.njk

            1
            {# src/_includes/contact-form.njk #}
          
            2
            <form action="https://formwire.io/submit" method="POST">
          
            3
              <input type="hidden" name="access_key" value="YOUR-ACCESS-KEY" />
          
            4
              <input type="hidden" name="redirect" value="https://example.com/thanks" />
          
            5
              <input type="text" name="fax" tabindex="-1" autocomplete="off" style="display:none" />
          
            6
             
          
            7
              <label for="name">Name</label>
          
            8
              <input id="name" type="text" name="name" required />
          
            9
             
          
            10
              <label for="email">Email</label>
          
            11
              <input id="email" type="email" name="email" required />
          
            12
             
          
            13
              <label for="message">Message</label>
          
            14
              <textarea id="message" name="message" rows="5" required></textarea>
          
            15
             
          
            16
              <button type="submit">Send</button>
          
            17
            </form>
          

Steps

  1. 1

    Create a form and copy its access key

    Sign up at app.formwire.com and create a form. Your sign-in address receives its submissions from the start. The access key is on the form's Settings tab, under General.

  2. 2

    Add the include

    Create src/_includes/contact-form.njk with the code above and replace YOUR-ACCESS-KEY with your key. An include keeps the form in one file for every page that shows it.

  3. 3

    Create the contact page

    Add a page that extends your layout and pulls the include in.

    html
    
                1
                ---
              
                2
                layout: base.njk
              
                3
                title: Contact
              
                4
                permalink: /contact/
              
                5
                ---
              
                6
                 
              
                7
                <h1>Contact</h1>
              
                8
                <p>Send us a message and we reply within one working day.</p>
              
                9
                 
              
                10
                {% include "contact-form.njk" %}
              
  4. 4

    Add the thank-you page

    Create src/thanks.njk with permalink /thanks/ and set the hidden redirect field to its full URL.

  5. 5

    Send a test submission

    Open the page with npx @11ty/eleventy --serve, fill the form in and send it. The submission appears in the form's inbox in the dashboard within a few seconds and the notification email follows, with Reply-To set to the address the visitor typed.

Notes for Eleventy

  • Liquid templates work the same way: name the files .liquid and use {% include "contact-form.liquid" %}.
  • Put the key in a global data file such as src/_data/site.json and write value="{{ site.formwireKey }}" in the include if you reuse it across sites.
  • In Markdown files, raw HTML passes through by default, so the include can also be dropped into a .md page with the same include tag.

Questions

Do I need Eleventy Serverless or an Edge function?

No. The form posts to Formwire, so the whole site stays static output. Serverless is only needed for pages that render per request, which a contact form does not.

Is the access key safe to put in client-side code?

Yes. The access key is a public ID that can only deliver submissions to the inbox you verified. It cannot read submissions or change settings, and you can rotate it from the form's settings if it is ever abused.

How does the form stop spam without a captcha?

The hidden fax field is a honeypot: a submission that fills it in goes to the Spam folder and nobody is emailed. A spam filter and rate limits also run on every form. Settings, Spam & security has the filter level, and on Pro, allowed domains.

Can I keep visitors on the page instead of redirecting?

Yes. Remove the redirect field and submit the form with fetch and an Accept: application/json header. The response is JSON with success and data.submission_id, and you show your own thank-you message. The React, Vue and Svelte guides do this.

All guides