# O atributo action do formulário HTML, explicado

> O que o atributo action de um formulário faz, como valores relativos e vazios são resolvidos, como formaction manda um formulário a dois lugares e por que hosts estáticos respondem 405.

Publicado em 2026-10-25 · https://ikiform.com/pt-br/guides/html-form-submission/action-attribute

O atributo `action` é a URL para onde um formulário envia os dados. Um valor relativo é resolvido a partir do endereço da página, um valor vazio ou ausente significa a própria página, e o `formaction` de um botão de envio o sobrescreve para aquele botão. Num site estático, defina-o como a URL completa de um backend de formulários, como `https://ikiform.com/f/<formId>`, porque o seu próprio host não aceita o POST.

A maioria dos formulários quebrados em sites estáticos está quebrada neste único atributo. O markup parece certo, o botão funciona, e o navegador mostra um `405` ou uma página em branco, porque os dados foram para um lugar que não consegue recebê-los. Esta página mostra exatamente para onde um dado `action` manda os dados, e depois usa `formaction` para direcionar um formulário a duas caixas de entrada.

## O que muda aqui

`action` é uma URL como qualquer `href`, com uma diferença: um formulário sem `action` não deixa de fazer algo, ele envia para a página em que está. Num site renderizado no servidor, essa página pode tratar o envio. Num host estático, não pode, então um `action` ausente ou relativo só falha depois do deploy.

## Para onde cada valor manda os dados

Pegue uma página em `https://example.com/company/contact.html` e cinco formulários nela:

`contact.html`:

```html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<form action="/api/contact" method="post">
<form action="send" method="post">
<form action="" method="post">
<form method="post">
```

| action | Resolve para | Num host estático |
| --- | --- | --- |
| `https://ikiform.com/f/frm_...` | Exatamente essa URL | Funciona. O Ikiform aceita o POST |
| `/api/contact` | `https://example.com/api/contact` | Só funciona se o seu host roda uma função nesse caminho |
| `send` | `https://example.com/company/send`, relativo à pasta | `405` ou `404` |
| `""` (empty) | A própria página, `contact.html` | `405` na maioria dos hosts estáticos |
| Ausente | A própria página | `405` na maioria dos hosts estáticos |

Diagrama: Como o navegador transforma o atributo action de um formulário na URL para onde envia

1. Um action absoluto é usado exatamente como escrito, então o envio chega ao Ikiform, que responde com um redirecionamento.
2. Um action relativo, vazio ou ausente é resolvido a partir do endereço da própria página, ou de um elemento base, se a página tiver um.
3. O envio então vai para o seu próprio host. Um host estático só serve arquivos, então recusa o POST, geralmente com 405.

Se a barra de endereço mostra o seu próprio domínio logo depois de enviar, o action era relativo.

> Um elemento `<base href>` no head da página muda como toda URL relativa é resolvida, inclusive o `action`. Alguns criadores de sites e configurações de single-page app adicionam um. Use uma URL completa e isso deixa de importar.

### Confira o que o navegador vai usar

No console do navegador, o atributo e a propriedade são diferentes. `getAttribute` devolve o que você escreveu; a propriedade `action` devolve a URL resolvida para onde o navegador vai realmente enviar:

`Console`:

```js
const form = document.querySelector("form");
form.getAttribute("action");
form.action;
```

Se `form.action` mostra o seu próprio domínio, é para lá que os dados vão. Criadores como Webflow e Framer costumam definir o `action` pelo próprio painel de configurações, então confira a página publicada, não o seu código-fonte. Os [guias de criadores de sites](https://ikiform.com/pt-br/docs/guides/site-builders.md) dizem onde cada criador guarda isso.

## Um formulário, duas caixas de entrada

O `formaction` de um botão de envio substitui o `action` do formulário só para aquele botão. Aqui, um único conjunto de campos vai para dois formulários do Ikiform. **Ask support** (falar com o suporte) envia ao formulário de suporte, **Talk to sales** (falar com vendas) ao formulário de vendas, e cada formulário do Ikiform avisa por e-mail os seus próprios destinatários:

`contact.html`:

```html
<form action="https://ikiform.com/f/frm_supportxxxxxxxxx" method="post">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />

  <label for="message">How can we help?</label>
  <textarea id="message" name="message" rows="5" required></textarea>

  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Ask support</button>
  <button formaction="https://ikiform.com/f/frm_salesxxxxxxxxxxx">Talk to sales</button>
</form>
```

- Cada formulário do Ikiform tem seus próprios destinatários de notificação, configurações de spam e webhooks, então suporte e vendas nunca veem os e-mails um do outro.
- Os dois formulários precisam da mesma definição de campos, ou de nenhuma. Com campos definidos, um campo que um formulário não conhece é recusado com `422`.
- Os outros atributos `form*` funcionam do mesmo jeito: `formmethod`, `formenctype`, `formnovalidate` e `formtarget`. Um botão **Save draft** (salvar rascunho) com `formnovalidate` pula as checagens do navegador.
- `formaction` só funciona em botões de envio: `<button>`, `<input type="submit">` e `<input type="image">`.

A alternativa é um único formulário do Ikiform com um campo `topic`, roteando por assunto num webhook ou nos filtros da sua caixa de entrada. Isso mantém uma lista e uma exportação. Dois formulários são mais simples quando as duas equipes não devem compartilhar destinatários de jeito nenhum.

## action com query string

Com `method="get"`, o navegador substitui a query string do action pelos campos do formulário. O `lang=de` no primeiro formulário abaixo é descartado em silêncio; o segundo o mantém como input oculto:

`search.html`:

```html
<form action="/search?lang=de" method="get">
  <input name="q" />
</form>

<form action="/search" method="get">
  <input name="q" />
  <input type="hidden" name="lang" value="de" />
</form>
```

Com `method="post"` a query string é mantida, porque os campos vão no corpo. Isso não muda nada para o Ikiform: parâmetros de query na URL do endpoint não são armazenados, então use inputs ocultos para valores que você quer guardar.

## Inputs fora do formulário

Às vezes o layout precisa de um input que não fica dentro do elemento `<form>`, como uma inscrição no rodapé ao lado de outro conteúdo. O atributo `form` num input ou botão o liga a um formulário pelo `id`, e ele envia para o `action` desse formulário:

`footer.html`:

```html
<form id="newsletter" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post"></form>

<footer>
  <input form="newsletter" name="email" type="email" required />
  <button form="newsletter">Subscribe</button>
</footer>
```

## Actions mailto: e javascript:

`action="mailto:you@example.com"` pede ao app de e-mail do visitante para abrir uma mensagem com os campos. Nada é enviado a menos que ele tenha um app de e-mail configurado e aperte enviar, e você nunca fica sabendo que ele tentou. `action="javascript:..."` roda código em vez de enviar e é bloqueado pela maioria das content security policies. Vale substituir os dois por um endpoint de verdade.

## Confira se funciona

1. Em **Allowed domains** do formulário, adicione o domínio do seu site, mais `localhost` enquanto desenvolve. Deixe vazio para aceitar envios de qualquer lugar.
2. Abra a página publicada, não o seu código-fonte, e rode `document.querySelector("form").action` no console. Ele imprime a URL completa do seu Ikiform.
3. Envie o formulário. O painel Network mostra um POST para `ikiform.com` respondido com `303`, não um POST para o seu próprio domínio.
4. No formulário com duas caixas de entrada, envie uma vez com cada botão. Cada envio aparece no seu próprio formulário no painel.
5. Confira a caixa de entrada de cada destinatário das notificações. Cada um recebe um e-mail com os campos, e **Reply** vai para quem enviou quando o formulário tem um campo `email`.

## Pegadinhas

| Problema | Causa e solução |
| --- | --- |
| `405 Method Not Allowed` vindo do seu próprio domínio | O action é relativo, vazio ou ausente, então o envio foi para o seu host estático. Use a URL completa do Ikiform |
| `404 not_found` vindo de ikiform.com | O id do formulário no action está errado, ou o formulário foi excluído. Copie o endpoint da página do formulário no painel |
| O criador de sites fica redefinindo o action | Alguns criadores controlam o `action` do bloco de formulário deles. Use a configuração de action personalizado deles, ou um embed com o seu próprio markup |
| O navegador avisa que o formulário não é seguro | O action usa `http:` numa página `https:`. O endpoint do Ikiform é só `https:`; corrija o esquema |
| Campos de um segundo formulário também são enviados | Formulários não podem ser aninhados. O navegador fecha o formulário externo na tag `<form>` interna. Use o atributo `form` em vez disso |

Para o fluxo completo de envio, do clique ao redirecionamento, veja a [visão geral](https://ikiform.com/pt-br/guides/html-form-submission.md#how-it-works). Tudo o que o endpoint aceita está em [Formulários HTML](https://ikiform.com/pt-br/docs/html.md).

## Perguntas

### O que acontece se um formulário não tem atributo action?

Ele envia para a página em que está. Isso funciona quando o seu servidor trata envios nessa URL, mas num host estático falha, geralmente com 405 Method Not Allowed.

### Qual a diferença entre action e formaction?

action é definido no formulário e vale para todo envio. formaction é definido num botão de envio e sobrescreve o action quando aquele botão é usado, então um formulário pode enviar para dois lugares.

### O action do formulário pode ser uma URL em outro domínio?

Sim. Os navegadores enviam cross-site sem nenhuma configuração especial, e é assim que uma página estática envia a um backend de formulários. O servidor que recebe decide se aceita; o Ikiform confere a origem da página com os domínios permitidos do formulário.

### Por que os parâmetros da query string somem da URL do action?

Com method get, o navegador substitui a query string do action pelos campos do próprio formulário. Mova cada parâmetro para um input oculto. Com method post a query string é mantida.

## Mais guias

- [Envio de formulários HTML](https://ikiform.com/pt-br/guides/html-form-submission.md): O que o navegador faz quando um formulário é enviado: quais campos manda, como os codifica, o que o servidor deve responder e como o Ikiform responde.
- [Redirecionar após o envio](https://ikiform.com/pt-br/guides/html-form-submission/redirect-after-submit.md): Mande visitantes para sua própria página de agradecimento depois do envio: o redirecionamento 303, o campo _redirect, quais domínios são permitidos e o que o refresh faz.
- [Sem recarregar a página](https://ikiform.com/pt-br/guides/html-form-submission/without-page-reload.md): Envie um formulário com fetch e FormData para o visitante continuar na página, com erros de campo, estado de carregamento, novas tentativas e um plano B quando scripts falham.
- [Validação de formulários](https://ikiform.com/pt-br/guides/html-form-submission/validation.md): Valide um formulário com required, type, pattern e min, estilize erros com :user-invalid e aplique as mesmas regras no servidor com definições de campos.
