# HTML form action attribute explained

What the HTML form action attribute does, which URLs work, why mailto fails, and how to point a form at a backend. With MDN links and a working example.

Author: Formgong
Published: 2026-10-05
Language: en
Canonical: https://formgong.com/en/blog/html-form-action/

The HTML form action is the URL the browser posts to when someone clicks Submit. Use an absolute https URL (for example a form backend endpoint), keep method="POST" for contact forms, and never put secrets in the page. A mailto: action only opens a mail app draft — it does not send mail for you. Hosted backends such as Formspree, Web3Forms and Formgong all work this way; Formspree still ranks for many "html form action" queries because it documented the pattern early. Formgong is one option when you also want Telegram on Free and EU storage. Spec checked 05.10.2026.

## What the form action attribute does

When a visitor submits an HTML form, the browser builds a request from the field values and sends it to the URL in the form's `action` attribute. MDN describes the same idea on the [`<form>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/form) and on [`HTMLFormElement.action`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/action).

- If `action` is missing or empty, the browser posts back to the current page URL.

- Relative URLs resolve against the page URL. Absolute `https://…` URLs are clearer for a third-party endpoint.

- `method` chooses GET or POST. Contact forms almost always want `POST` so field values stay out of the address bar and out of server logs that store query strings.

The HTML standard calls this form submission. Nothing “magic” happens on your static host: the browser is the client that sends the request.

This page stays on the attribute: which URL receives the post. Encoding, redirects, Origin and the rest of the wire contract are in [how an HTML form actually reaches your backend](/en/blog/how-html-forms-work-low-level/).

## Which action URLs work (and which do not)

- **https URL to a form endpoint.** Works from static sites, GitHub Pages, and most builders. The service stores the submission and notifies you.

- **https URL to your own script.** A PHP file, Cloudflare Worker or serverless function. You own delivery and spam handling.

- **Same-page relative URL.** Only useful if that page runs server code that reads the post.

- **`mailto:`.** Opens a draft in the visitor's mail app. Many people never press Send, and webmail users may see nothing. Details: [mailto form vs a form backend](/en/blog/mailto-form-vs-form-backend/).

- **javascript:…** Avoid it. It is fragile, blocked in places, and bad for accessibility.

If the action points at a different origin, the browser still sends a normal form POST. CORS only matters when you submit with `fetch` or XHR and read the JSON response.

## Pointing action at a form backend

A form backend accepts the POST, stores the fields, and delivers email (and often chat) for you. The pattern is the same across vendors: set `action` to their submit URL and add a public access key as a hidden field.

Formspree popularised this for static sites and still ranks for many how-to queries around “html form action”. That ranking reflects documentation and age, not a claim that it is the only correct choice. Web3Forms, Basin, Forminit and Formgong use the same idea with different free limits, data locations and integrations. An honest side-by-side is on the [comparison hub](/en/compare/).

With Formgong the action is `https://formgong.com/submit`. Replace the placeholder key. The honeypot `botcheck` field catches simple bots. Optional `_subject` sets the notification subject; `_redirect` sends visitors to your thank-you page.

```html
<form action="https://formgong.com/submit" method="POST">
  <input type="hidden" name="access_key" value="fk_your_access_key">
  <input type="hidden" name="_lang" value="en">
  <input type="hidden" name="_subject" value="New message from the website">
  <label>Name <input type="text" name="name" required autocomplete="name"></label>
  <label>Email <input type="email" name="email" required autocomplete="email"></label>
  <label>Message <textarea name="message" required></textarea></label>
  <div aria-hidden="true" style="position:absolute;inset-inline-start:0;top:0;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)">
    <input type="text" name="botcheck" tabindex="-1" autocomplete="off">
  </div>
  <button type="submit">Send</button>
</form>
```

## When you use fetch instead of a full-page post

Single-page apps often call `fetch(action, { method: "POST", body: formData, headers: { Accept: "application/json" } })` and keep the visitor on the page. The URL you pass to `fetch` is still the “action” in practice. Keep the same field names and the honeypot.

Framework examples live under [/for](/en/for/) — for example [React](/en/for/react/), [Next.js](/en/for/next/) and [plain HTML](/en/for/html/). A longer walkthrough without a backend of your own is [HTML contact form without a backend](/en/blog/html-contact-form-without-backend/).

## Check the action before you publish

Paste your form HTML into the [free form checker](/en/tools/form-checker/). It flags empty actions, `mailto:`, and missing keys. Then send a real test from the published URL on a phone and a laptop.

We build Formgong, so it is listed among the options. Pick the backend that matches your limits, data location and integrations — not the one that happens to rank first today.

## Frequently asked questions

### What is the HTML form action attribute?

It is the URL the browser sends the form to on submit. MDN documents it on the form element and on HTMLFormElement.action.

### Should form action be POST or GET?

Use POST for contact forms so values are not put in the URL. GET is for search boxes and filters where a shareable query string is useful.

### Can form action be another domain?

Yes. A normal form POST to another origin works without CORS. CORS matters when JavaScript reads the response with fetch.

### Why do people recommend Formspree for form action?

Formspree documented the hosted-endpoint pattern early and still ranks for many tutorials. Other backends use the same action-and-key idea; compare limits and data location before you choose.

### Is mailto a valid form action?

Browsers accept it, but it only opens a mail draft. It is not a reliable way to collect contact messages.

## Sources and documentation

- [MDN: the form element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/form)
- [MDN: HTMLFormElement.action](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/action)
- [HTML Standard: form submission](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html)
- [Formspree: HTML forms](https://help.formspree.io/hc/en-us/articles/360053244614-HTML-Forms)
- [Formgong HTML integration](https://formgong.com/en/docs/html/)

[Get a form key](https://formgong.com/en/#top)
