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

Forms

Files: src/config/config.toml, src/content/sections/<language>/contact-section.md, src/content/sections/<language>/newsletter-section.md · Skill level: Beginner

Margo is a static site: it has no server of its own to receive messages. Each form sends its answers to a service you choose, which emails them to you or keeps them in a dashboard. There are two kinds:

FormWhere it appearsSends to
Contact form/contact/, or any page with a contact sectionFormsubmit, Formspree, or Netlify Forms
Newsletter formsThe journal pages (newsletter section) and the columns footerMailchimp

Until an endpoint is set, npm run dev shows a warning inside each form, and npm run dev and npm run build print one in the terminal. Visitors of the built site never see these warnings, but their messages go nowhere until you set the endpoints.

Connect The Contact Form

Pick a provider and set both lines in the [settings] table of config.toml:

No account needed. Messages arrive by email.

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

The first message sent through the form triggers an activation email from Formsubmit. Open it and confirm, or later messages won’t be delivered.

The dev warning also tells you when the address doesn’t look like the provider you picked, for example a Formspree address with contactFormProvider = "formsubmit.co". After launch, send one real message from the live site to make sure it arrives.

Change The Contact Form Fields

The fields are in src/content/sections/<language>/contact-section.md, under form.inputs. A page can set its own list in its contactSection: block, and that list replaces the default one on that page.

form:
emailSubject: "New project enquiry from your website" # subject of the email you receive
submitButton:
enable: true
label: "Send the brief"
inputs:
- label: "Email"
name: "Email" # the field name in the message you receive
placeholder: "[email protected]"
type: "email"
required: true
halfWidth: true # two fields share a row on wider screens
- label: "Budget"
name: "Budget"
dropdown:
type: "select" # select | search (a list with a search box)
items:
- label: "Under €5,000"
value: "Under €5,000"
- label: "About the project"
name: "Message"
tag: "textarea"
rows: "6"
required: true
- label: "I agree that my details are used to answer this message. Read the [privacy policy](/privacy-policy/)."
name: "Consent"
value: true
type: "checkbox"
required: true
Field typeHow to write it
TextNo type, or type: "text"
Email, phone, web address, number, datetype: "email", "tel", "url", "number", "date"
Long texttag: "textarea" and rows
Dropdowndropdown: with type and items (label and value each)
Checkbox or radio buttonstype: "checkbox" or "radio". Fields that share a group show as one set under groupLabel

Other options: required (adds the * mark), halfWidth, placeholder, and defaultValue. Every field needs a visible label.

The last two items of inputs are not fields: the one with note: success holds the message shown after a message is sent, and the one with note: deprecated the message shown when sending fails. Edit their content (Markdown) to change the wording:

- note: success
content: "**Thank you, your brief is in.** I read every message myself and reply within a day."
- note: deprecated
content: "**The message did not go through.** Please try again in a moment, or write to me by email."

form.note adds a line under the form, in Markdown. Change the fields in every language folder. The section files have no schema, so npm run astro-check doesn’t report a mistyped option there. Open /contact/ after each change and send a test message.

The details and the booking card beside the form are explained in Contact & Booking.

Connect The Newsletter (Mailchimp)

  1. In Mailchimp, open Audience > Signup forms > Embedded forms.

  2. In the embed code, find <form action="..."> and copy the URL. It looks like https://xxxx.us1.list-manage.com/subscribe/post?u=...&amp;id=....

  3. Paste it into config.toml, then change every &amp; to a plain &:

    [settings.subscription]
    enable = true
    formAction = "https://xxxx.us1.list-manage.com/subscribe/post?u=abc123&id=def456&f_id=0012ab"
  4. Optional: mailchimpTagValue adds a Mailchimp tag to every new subscriber, so you can tell where they came from.

  5. After you deploy, subscribe once with a test address and check that it appears in your Mailchimp audience.

enable = false removes every newsletter form at once. If you don’t send a newsletter, set it to false.

The newsletter forms post to Mailchimp only. To use another email service, the form component (src/layouts/components/widgets/SubscriptionForm.astro) needs a code change.

Newsletter Text

  • The journal pages (/blog/, its other pages, and the category and tag pages) show the newsletter section. Its heading, line, and the small print under the form (note) are in src/content/sections/<language>/newsletter-section.md, and the journal can change them in the newsletterSection: block of src/content/blog/<language>/-index.mdx.
  • The columns footer shows a newsletter form beside its heading. Its text is the newsletter block of src/content/sections/<language>/footer.md; enable: false there hides it in the footer only. See Footer.
  • The button label and the success and error messages are under subscription in src/i18n/<language>.json, in every language.

Do It With AI

Connect my forms. Contact form: [Formsubmit with EMAIL | Formspree with ID | Netlify Forms]; set
contactFormAction and contactFormProvider in src/config/config.toml following its comments.
Newsletter: here is my Mailchimp embed form action: [URL]; set [settings.subscription] formAction
and replace every &amp; with &. Then change the contact form fields in
src/content/sections/english/contact-section.md (and the french and arabic files) to: [FIELDS].
Keep the note: success and note: deprecated items at the end. Run npm run dev and tell me if any
form warning is left.
Type something to search...