Skip to content
New: Customize your theme with an AI assistant. Read the guide

Forms

Files: src/config/config.toml, src/content/sections/english/contact-section-two.md · Skill level: Beginner

Ecozen contact page with the quote form

Ecozen’s main form is the quote request on /contact/, beside a card with your contact details. Ecozen is a static site, so the form sends its answers to a service you choose, which emails them to you or stores them.

The short form in the contact band section and the quote card of the form hero send to the same address. The email sign-up in the newsletter footer has its own address, in [settings.newsletter] (see Footer).

The form has three steps (property, energy use, contact). With JavaScript, visitors see one step at a time, with a progress bar, Next and Back buttons, and “Step 1 of 3”. Next checks the required fields of the current step before it moves on. Without JavaScript, all steps show as one long form that still submits.

Connect The Form

The theme ships with a placeholder address (https://formsubmit.co/[email protected]). Until you replace it, requests go nowhere. Pick a provider and set both lines in config.toml:

Free, no account needed. Requests arrive by email, as a table of the answers.

[settings]
contactFormAction = "https://formsubmit.co/[email protected]"
contactFormProvider = "formsubmit.co"

The first request you send triggers an activation email from Formsubmit. Open it and confirm, or later requests won’t be delivered.

After launch, send one real request from the live site to make sure it arrives.

Check The Setup

Ecozen checks both form addresses (contactFormAction with contactFormProvider, and action with provider in [settings.newsletter]) whenever it renders a page that shows that form (the newsletter form shows only in the newsletter footer). It warns when an address is empty, is still a placeholder, names a provider the theme doesn’t know, or doesn’t match the provider, for example a Formspree address with contactFormProvider = "formsubmit.co".

  • In the terminal: npm run dev and npm run build print a line that starts with a yellow [forms] tag, names the form (contact or newsletter) and the problem, and says which keys to set.
  • On the dev server: after you submit the form, a “Dev only · form not connected” note appears inside it with the same reason. It never shows when the page loads, and never on a built or deployed site, so check the terminal before you deploy.

The check knows the shape of each provider’s address: https://formsubmit.co/..., https://formspree.io/f/..., and a path such as / for Netlify. A newsletter with provider = "" can post to any address, so only a placeholder address is reported there. An empty newsletter action hides the sign-up form instead.

Change The Questions

The form lives in src/content/sections/english/contact-section-two.md (and the other language folders), under form. The contact page file can override it with a contactSection block, but ships with enable: true only, so edit the section file.

Steps. form.steps lists the steps in order. Each field has a step number that puts it in that step:

form:
emailSubject: "New quote request from the website" # subject of the email you receive (Formsubmit and Formspree)
steps:
- title: "Property"
description: ""
- title: "Energy use"
description: ""
- title: "Contact"
description: ""
stepNav:
stepLabel: "Step" # "Step 1 of 3"
ofLabel: "of"
nextButton:
label: "Next"
variant: "fill"
backButton:
label: "Back"
variant: "outline"
submitButton:
enable: true
label: "Send my request"
variant: "fill"

To make a one-step form, remove steps (or leave one step) and the step numbers.

Fields. Each item of inputs is one field:

inputs:
- label: "Full name"
placeholder: "Your name"
name: "Full name" # the field name in the request you receive
autocomplete: "name"
required: true
halfWidth: true # two fields per row on large screens
step: 3
- label: "Message"
tag: "textarea"
rows: "4"
name: "Message"
step: 3

Choices. Radio buttons and checkboxes are one item per choice. Items with the same group are shown together, and the first one carries the groupLabel (the question) and inline: true (choices in a row):

- label: "Home"
name: "Property type"
value: "Home"
checked: true # selected by default
required: true
groupLabel: "Property type"
group: "property"
type: "radio"
inline: true
step: 1
- label: "Business"
name: "Property type"
value: "Business"
required: true
group: "property"
type: "radio"
step: 1
Field typeHow to write it
TextNo type, or type: "text"
Email, phone, numbertype: "email", "tel", or "number"
Long texttag: "textarea" and rows
Radio buttonstype: "radio", one item per choice, with a shared group and name
Checkboxestype: "checkbox", one item per choice, each with its own name
Dropdowndropdown: with type (select or search) and items

Other options: required, placeholder, autocomplete, defaultValue, and id.

The privacy checkbox near the end (id: "privacy-policy") links to your terms and privacy policy in its label. Keep it, and keep the links pointing at your real pages.

Messages. The last two items of inputs are not fields: the one with note: success holds the message shown after a request is sent, and the one with note: deprecated the message shown when sending fails. Edit their content and keep their parentClass:

- note: success
parentClass: "hidden text-sm message success"
content: "Thank you. We have your request and an energy advisor will contact you within one working day."
- note: deprecated
parentClass: "hidden text-sm message error"
content: "Something went wrong. Please email [[email protected]](mailto:[email protected]) and we will follow up."

Replace [email protected] there, and in contactForm.fallbackTicketMessage in each file in src/i18n/, with your own address.

The section file has no schema, so npm run astro-check doesn’t report a mistyped option. Open /contact/, step through the form, and send a test request after each change.

The Contact Details Card

The card beside the form lists phone, email, address, and hours from [settings.contactInfo] in config.toml, as plain lines with a small label above each value. Each item in list of contact-section-two.md picks one with settingFieldName; its title is the label (the icon field is kept in the file but not shown). Set value on an item to show other text instead, for example translated opening hours in the French file:

list:
- title: "Opening hours"
icon: "Clock"
settingFieldName: "hours"
value: "Lun–Ven, 8h00–18h00"

Do It With AI

Connect the quote form to [Formsubmit with EMAIL | Formspree with form ID | Netlify Forms]: set contactFormAction and
contactFormProvider in src/config/config.toml following its comments. Then change the questions in
contact-section-two.md in every language folder of src/content/sections/ to: step 1 [QUESTIONS], step 2
[QUESTIONS], step 3 [CONTACT FIELDS]. Keep the steps structure, the privacy checkbox, and the two
message items, and replace [email protected] with [EMAIL] in the messages and in
contactForm.fallbackTicketMessage in every file in src/i18n/.
Type something to search...