# Forms (Contact & Newsletter)

## 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:

| Form             | Where it appears                                                         | Sends to                                |
| ---------------- | ------------------------------------------------------------------------ | --------------------------------------- |
| Contact form     | `/contact/`, or any page with a contact section                          | Formsubmit, Formspree, or Netlify Forms |
| Newsletter forms | The journal pages (newsletter section) and the `columns` footer          | Mailchimp                               |

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`:

<Tabs>
  <TabItem label="Formsubmit (default)">

    No account needed. Messages arrive by email.

    ```toml
    [settings]
      contactFormAction   = "https://formsubmit.co/you@yourdomain.com"
      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.

  </TabItem>
  <TabItem label="Formspree">

    Create a form at [formspree.io](https://formspree.io/) and copy its endpoint.

    ```toml
    [settings]
      contactFormAction   = "https://formspree.io/f/your-form-id"
      contactFormProvider = "formspree"
    ```

  </TabItem>
  <TabItem label="Netlify Forms">

    Only when the site is hosted on Netlify.

    ```toml
    [settings]
      contactFormAction   = "/"
      contactFormProvider = "netlify"
    ```

    Turn on form detection in the Netlify dashboard (**Forms**), deploy, and send a test message. Check that it appears in the dashboard before you rely on the form.

  </TabItem>
</Tabs>

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.

```yaml
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: "you@yourstudio.com"
      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 type     | How to write it                                                                  |
| -------------- | -------------------------------------------------------------------------------- |
| Text           | No `type`, or `type: "text"`                                                     |
| Email, phone, web address, number, date | `type: "email"`, `"tel"`, `"url"`, `"number"`, `"date"`  |
| Long text      | `tag: "textarea"` and `rows`                                                     |
| Dropdown       | `dropdown:` with `type` and `items` (`label` and `value` each)                   |
| Checkbox or radio buttons | `type: "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:

```yaml
    - 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](/margo/customization/contact-booking/).

### Connect The Newsletter (Mailchimp)
<Steps>

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 `&`:

   ```toml
   [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.

</Steps>

`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.

<Aside type="caution" title="Why the plain ampersand matters">
  The embed code writes `&amp;` between parameters. If you keep it, Mailchimp
  receives a broken list address and the signup fails. The dev warning
  reminds you.
</Aside>

### 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](/margo/customization/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
```text
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.
```