# Add forms to a static site

> Collect contact requests and sign-ups on a static Astro site with Netlify Forms or an n8n webhook, with spam protection and notifications.

Source: https://viralistic.nl/help/astro/forms

A static Astro site has no server of its own, so a form needs somewhere to send its data. This article is for developers and site owners who want a working contact or sign-up form without running a backend. You will learn the two routes Viralistic uses, how to set up each one, and how to keep spam and personal data under control.

## Choose a route

| Route         | Best for                                       | What happens to a submission                                                     |
| ------------- | ---------------------------------------------- | -------------------------------------------------------------------------------- |
| Netlify Forms | Contact forms, quote requests, simple sign-ups | Stored in Netlify, emailed to you, optionally forwarded                          |
| n8n webhook   | Forms that should start a process              | Sent to an n8n workflow that can write to a CRM, send replies or alert a channel |

You can also combine them: Netlify Forms catches the submission and filters spam, then forwards it to n8n.

## Set up Netlify Forms

Netlify reads the built HTML during each deploy, finds forms marked for Netlify and registers them. No extra code runs on a server.

### Enable form detection

1. Open your project in Netlify.
2. Go to the **Forms** section and enable form detection.
3. Deploy the site again. Detection only happens during a deploy.

### Mark up the form

Give the form a `name`, add `data-netlify="true"` and include a hidden `form-name` field with the same name:

```astro
<form
  name="contact"
  method="POST"
  data-netlify="true"
  netlify-honeypot="bot-field"
>
  <input type="hidden" name="form-name" value="contact" />
  <p hidden>
    <label>Leave this empty <input name="bot-field" /></label>
  </p>
  <label>Name <input name="name" required /></label>
  <label>Email <input type="email" name="email" required /></label>
  <label>Message <textarea name="message" required></textarea></label>
  <button type="submit">Send</button>
</form>
```

The `bot-field` is a honeypot: people never see it, bots fill it in, and Netlify silently drops those submissions. Netlify also filters spam on its side.

> **Note:** On a Viralistic site, the form lives in a block (for example `contact-1.astro`) and the labels, placeholders and success message come from the page's frontmatter. Do not hard-code copy in the component.

### Submit without leaving the page

By default the browser goes to a Netlify confirmation page after submitting. To show your own success message instead, send the form with JavaScript. This is the pattern the Viralistic contact block uses:

```ts
form.addEventListener("submit", async (event) => {
  event.preventDefault()
  const body = new URLSearchParams(
    new FormData(form) as unknown as Record<string, string>
  )
  const response = await fetch("/", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: body.toString(),
  })
  if (response.ok) form.reset()
})
```

Alternatively, add `action="/thank-you"` to the form and create a thank-you page as a normal markdown file.

### Get notified

1. In Netlify, open the form notification settings.
2. Add an email notification to the address that should receive submissions.
3. Optionally add an outgoing webhook to forward each submission to n8n or another tool.
4. Send a test submission from the live site and check that it arrives.

> **Tip:** Netlify only detects forms in the HTML it builds. If a form only appears after JavaScript runs, Netlify will not find it. Astro renders forms as plain HTML, so this rarely bites on a Viralistic site.

## Send forms to n8n

When a submission should trigger work (create a lead in your CRM, send a personal reply, book a follow-up), post it to an n8n workflow.

1. In n8n, create a workflow that starts with a Webhook node set to accept `POST`.
2. Copy its production URL and activate the workflow.
3. Either set that URL as the form's `action`, or keep Netlify Forms and add the URL as an outgoing webhook notification.
4. Add the steps you need after the webhook, and end with a clear response for the visitor.

See [Receive data with webhooks](https://viralistic.nl/help/n8n/webhooks) for the details of the Webhook node.

> **Warning:** A webhook URL that the browser posts to directly is public. Validate the input in the workflow, ignore submissions with a filled honeypot field and never let a form trigger anything expensive without a check.

## Privacy and good practice

- Ask only for what you need. Every extra field lowers the number of people who finish the form.
- Mention in your privacy policy where submissions are stored (Netlify, n8n, your CRM) and how long you keep them.
- Use real `<label>` elements so the form works with screen readers.
- Test the form after every redesign. A broken contact form is often only noticed when the leads stop.

## Next steps

- [Receive data with webhooks](https://viralistic.nl/help/n8n/webhooks)
- [Deploy to Netlify](https://viralistic.nl/help/astro/deploy-to-netlify)
- [Error handling and alerts](https://viralistic.nl/help/n8n/error-handling)
