Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Forms Hugo Module

This module enables forms from several services on a Hugo Projects

Supported Services

  • Netlify Forms
  • Formspree
  • CloudCannon



  • Go 1.14
  • Hugo 0.61.0


If not already, init your project as Hugo Module:

$: hugo mod init {repo_url}

Configure your project's module to import this module:

# config.yaml
  - path:


Currently the Module supports can be used with any host, while the other two only work if hosting with them.


Formspree requires the Form ID passed to the Form's Data as formspree_id


A CloudCannon form inbox must be created on the CloudCannon dashboard of your site/organizzation. Then user can use inbox_key to assign the inbox to the form. Without the key, we'll use the form's id.


Create Forms

Forms are handle as unique data files stored under data/tnd-forms

Form data

id: contact
# if using Formspree
formspree_id: sxewrre33
# If using CloudCannon: It defaults on the form's `id` set above.
inbox_key: concat-cc-en
title: Contact Us
redirect: /thank-you/
submit: Get in touch
  version: 3
  key: 6LctEP0fAAAxxxxxxxxxxxxxxxxxxxxxx
- name: name
  required: true
  label: Name
- name: message
  label: Message
  type: textarea
  • id: Will be used to identify the form when calling from shortcode.
  • title: The title displayed above the form
  • redirect: If successful submission should redirect to a page (Not available on Formspree free plan)
  • submit: Text for the submit button
  • recaptcha: reCaptcha A map with Key (key) and optional version, if set, the form will load the recaptcha script and load the g-recaptcha div
  • fields: List of fields for which data will be detailed below

Field data

- name: name
  label: Full Name
  type: text
  • name: String to be used as name attribute
  • label: String to be used as label. Can include markdown.
  • type: The type of input as detailed below.

Add form to pages.

A single argument shortcode can be added to any content file's body. The argument should be a string matching the form's id.

title: Contact Us

Fill free to fill the form below to get in touch...

{{< tnd-form "contact" >}}

Add form to templates.

Any form can be invoked from within a template using the tnd-forms/form.html partial. The context should be a string matching the form's id.

<!-- layouts/_default/contact.html -->
{{ define "main" }}
<section class="content">
  {{ .Content }}
<section class="contact">
  {{ partial "tnd-forms/form" "contact" }}
{{ end }}

Built in Field types

text|phone|email|file|textarea: Will use the same template with the defined type attribute

  - name: name
    label: Full Name
    type: text

select: A select field. Takes one extra key (options)

  - name: state
    label: State
    type: select
    - Alabama
    - Alaska

checkboxes|radios: A multiple choice field using either checkboxes or radios. Use radios type for radios and checkboxes for multiple checkboxes.

  - name: source
    label: How did you hear from us?
    type: radios
      - A friend
      - Internet
      - Ad


A single checkbox field

  - type: checkbox
    name: agree
    label: Do you agree with everything we will ever say?


A hidden field

  - type: hidden
    name: lang_code
    # `label` will be used to fill the `value` attribute if `value` is not set:
    label: en
    value: en

In absence of the value setting, the module will use a hidden field's label setting for the value attribute.


Settings are added to the project's parameter under the tnd_forms map as shown below.

# config.yaml
    provider: formspree
      submit: border p-4


Any form can be using a specific provided among the supported ones. To specify a global default provider, use this key. Default is netlify.


Using a Google reCapatcha?, You shoud set both key and desired version on the form data itself like so:

id: contact
title: Contact Us
  version: 3
  key: 6LctEP0fAAAxxxxxxxxxxxxxxxxxxxxxx

version is optional and will default to 2 for Netlify and 3 for other providers.

WARNING: Netlify only supports V2. For V3 you should use Formspring or CloudCannon.


A map containing certain HTML elements produced by the Module's templates. Built-in class key are:

  • form
  • control
  • hidden
  • submit
  • input
  • textarea
  • select


With the following data file.

# data/tnd-forms/contact-form.yaml
id: contact
title: Contact Us
redirect: /thank-you/
submit: Get in touch
  - name: name
    required: true
    label: Name
  - name: email
    label: Email
    type: email
    required: true
  - name: reason
    label: Reason for inquiry
    type: select
      - Troubleshoot
      - Delivery
      - Financial
  - name: message
    label: Message
    type: textarea


Module can load its own very basic styling by loading tnd-forms/head.html partial inside your project's template's <head> tag.

  <title>My Website</title>
  {{ partialCached "tnd-forms/head.html" . }}

WARNING: The above requires Hugo's extended version for SCSS processing.

Styling through CSS classes.

User can define which CSS classes to be added to each HTML elements printed by the Module. See config

Styling through HTML templates

Overwriting any input type HTML template is easy. Simply add to your project layouts/partials/tnd-forms/inputs directory any file named after an existing input type.

  • default.html
  • select.html
  • hidden.html
  • textarea.html etc...

Check the original files for the available context.


Adding your own field type.

The module will pickup any templates from the layouts/partials/tnd-forms/inputs matching the type set in a form's field's data.

To create your fancy color picker, simply create its HTML at layouts/partials/tnd-forms/inputs/color-picker.html

And add the following field to one of your fields:

  - name: color
    label: Color
    type: color-picker
      - '#444'
      - '#ccc'

Note that any data passed to the field will be made available to your template's context alongside the setting's css object.


This project is maintained and loved by thenewDynamic.


Hugo Module for service abstracted forms







No releases published


No packages published