# Envie um formulário HTML para o e-mail sem PHP

> Substitua um script contact.php que chama mail() por um formulário que envia a um endpoint hospedado, mantendo seus nomes de campo, sua página de agradecimento e as respostas.

Publicado em 2026-10-25 · https://ikiform.com/pt-br/guides/send-form-to-email/without-php

Troque o `action` do formulário do seu script PHP pela URL de um backend de formulários, mantenha os nomes dos campos e apague o script. O backend faz o que o `mail()` fazia, mais as partes que ele nunca fez bem: filtro de spam, armazenamento e e-mails que não caem no spam. Funciona em hosts estáticos, onde o PHP nem roda.

## O que muda aqui

A maioria dos formulários de contato em PHP são as mesmas vinte linhas, copiadas de um tutorial anos atrás. Eles leem `$_POST`, montam uma string, chamam `mail()` e redirecionam. Este é um exemplo típico:

`contact.php`:

```php
<?php
$name = $_POST["name"];
$email = $_POST["email"];
$phone = $_POST["phone"];
$message = $_POST["message"];

$to = "hello@example.com";
$subject = "Website enquiry from $name";
$body = "Name: $name\nEmail: $email\nPhone: $phone\n\n$message";
$headers = "From: $email\r\nReply-To: $email";

if (mail($to, $subject, $body, $headers)) {
  header("Location: /thanks.html");
} else {
  echo "Sorry, something went wrong.";
}
```

Parece inofensivo, e funcionava quando foi escrito. Hoje ele quebra de quatro formas, e só a primeira é óbvia:

| Problema | Por que acontece |
| --- | --- |
| Sem PHP no host | GitHub Pages, Netlify, Vercel, Cloudflare Pages e S3 servem arquivos; eles não rodam PHP. O formulário envia para um arquivo que nunca é executado, e você recebe um `404` ou `405`. |
| O e-mail cai no spam ou some | O `mail()` entrega a mensagem ao programa de e-mail local do servidor. O header `From:` diz ser o endereço do visitante, mas o e-mail sai do servidor do seu host, então falha nas verificações de SPF e DMARC do domínio do visitante. O Gmail e o Outlook filtram ou rejeitam, muitas vezes sem avisar. |
| Injeção de headers | O `$email` entra nos headers sem verificação. Um bot que envia um valor com quebra de linha pode adicionar a própria linha `Bcc:` e usar seu formulário para mandar spam, o que coloca o IP do seu host em listas de bloqueio. |
| Nada é guardado | Se o e-mail se perde, a mensagem se perde junto. Não há registro, nem filtro de spam, nem como rever os contatos do mês passado. |

Você poderia corrigir cada um: validar todos os valores, enviar por um provedor SMTP com uma biblioteca como o PHPMailer, configurar SPF e DKIM para o seu domínio, adicionar um honeypot e um limite de taxa e registrar tudo num banco de dados. É um projeto razoável se você já roda PHP. Se preferir não fazer isso, passe o trabalho para um backend de formulários.

Diagrama: O mesmo formulário com mail() do PHP e com um backend de formulários

1. Com o contact.php, o formulário envia ao seu host, e o mail() envia uma mensagem que diz vir do visitante. Os servidores de destino veem um remetente que não bate com o domínio e o jogam no spam ou o descartam.
2. Com um backend de formulários, o formulário envia os mesmos campos ao Ikiform. O Ikiform envia o e-mail do próprio domínio e coloca o endereço do visitante em Reply-To, que é para isso que o Reply-To serve.

A solução para a entregabilidade não é um script melhor. É enviar de um domínio que tem permissão para enviar.

## Tire o formulário do PHP

Mantenha os nomes dos campos exatamente como estão. Só o `action` muda, mais dois inputs ocultos:

`Antes`:

```html
<form action="/contact.php" method="post">
  <input name="name" required />
  <input name="email" type="email" required />
  <input name="phone" type="tel" />
  <textarea name="message" required></textarea>
  <button>Send</button>
</form>
```

`Depois`:

```html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <input name="name" required />
  <input name="email" type="email" required />
  <input name="phone" type="tel" />
  <textarea name="message" required></textarea>
  <input type="hidden" name="_redirect" value="https://example.com/thanks.html" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send</button>
</form>
```

Depois relacione cada coisa que o script fazia com o lugar onde ela fica agora:

| No contact.php | Agora |
| --- | --- |
| `$to = "hello@example.com"` | Destinatários nas configurações de **Notifications** do formulário |
| `header("Location: /thanks.html")` | O input oculto `_redirect`, ou **Redirect after submit** nas configurações do formulário |
| `Reply-To: $email` | Automático, porque o campo se chama `email` |
| `$subject = "Website enquiry from $name"` | Fixo como `New submission: <form name>`. Dê ao formulário o nome "Contato pelo site" para manter o texto |
| `echo "Sorry, something went wrong."` | A página de erro do Ikiform para um envio simples, ou sua própria mensagem com `fetch` |
| Verificações que você nunca escreveu | O honeypot `_gotcha`, a pontuação de spam, os limites de taxa e a validação de campos |

- Adicione seu domínio em **Allowed domains**. `_redirect` só funciona com uma URL `https:` num desses domínios.
- Apague o `contact.php` do servidor quando o novo formulário estiver funcionando. Um script esquecido continua sendo um relay de e-mail aberto para bots que lembram a URL.
- Se você migrou para um host estático, a antiga URL `/contact.php` não existe mais. Bots que enviam direto para ela recebem um `404`, o que está ótimo.

> Se o seu formulário era um plugin do WordPress em vez de um script, a mesma ideia vale. O [guia do WordPress](https://ikiform.com/pt-br/docs/guides/wordpress.md) mostra onde colocar o formulário num tema de blocos.

## 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. Envie o formulário na sua página publicada. Você cai no seu antigo `thanks.html`.
3. Abra **Submissions** no painel. O novo envio está lá com todos os campos que você enviou.
4. Abra o e-mail. Ele vem do Ikiform, não do endereço do visitante, e não está no spam. Adicione o remetente aos seus contatos para que os próximos também não caiam.
5. Clique em **Reply**. O endereço do visitante está na linha **To**.
6. Envie com o honeypot preenchido, `_gotcha=bot`. Ele ainda recebe uma resposta de sucesso, mas o envio é armazenado como spam e não dispara e-mail nem webhook.

## Pegadinhas

- **Nomes antigos com colchetes.** Formulários PHP muitas vezes usam nomes como `contact[email]`. O Ikiform os armazena como estão, mas o reply-to só vem de um campo chamado `email` ou de algumas variações próximas. Renomeie o campo ou adicione `_replyto`.
- **O assunto não pode incluir o nome.** O assunto do script tinha o nome do visitante. O assunto da notificação é fixo, e `_subject` é repassado aos webhooks e à API sem mudar o e-mail.
- **Codificação de caracteres.** Scripts com `mail()` muitas vezes estragavam os acentos porque nunca definiam um charset. O e-mail do Ikiform é UTF-8, então nomes em qualquer alfabeto chegam intactos.
- **Vários endereços em `$to`.** Uma lista separada por vírgulas no script vira destinatários separados no painel. Endereços de fora confirmam por link antes de receber qualquer coisa. Veja [vários destinatários](https://ikiform.com/pt-br/guides/send-form-to-email/multiple-recipients.md).

## Se algo der errado

| Problema | O que fazer |
| --- | --- |
| O navegador cai na página de agradecimento do Ikiform em vez da sua | O `_redirect` é ignorado, a menos que o domínio dele esteja em **Allowed domains** e ele seja uma URL `https:`. Adicione o domínio, ou defina **Redirect after submit** nas configurações do formulário. |
| `403 origin_not_allowed`, ou todo envio cai no spam | O domínio da página não está em **Allowed domains** do formulário. Adicione-o, mais `localhost` para testes locais. Subdomínios de um domínio listado são permitidos. |
| O formulário ainda envia para o arquivo PHP | Uma página em cache ou uma segunda cópia do formulário, como um include no rodapé, ainda tem o `action` antigo. Procure `contact.php` no site. |
| O envio está no painel, mas nenhum e-mail ou webhook chegou | Ele foi armazenado como spam. Spam não envia nada. Abra-o no filtro **Spam** para ver os motivos e marque-o como não spam para enviar o e-mail e os webhooks dele. |

## Perguntas

### Meu formulário antigo continua funcionando enquanto eu faço a troca?

Sim. O script antigo continua funcionando até você mudar o action do formulário, então você pode testar o novo endpoint numa cópia da página primeiro, depois trocar e apagar o script.

### Posso enviar um formulário HTML para o e-mail sem PHP?

Sim. Aponte o action do formulário para um backend de formulários em vez de um script PHP. O backend recebe o envio e manda um e-mail para você, então o seu site pode ser HTML puro em qualquer host estático.

### Por que os e-mails do mail() do PHP vão para o spam?

Os scripts costumam definir o header From com o endereço do visitante, mas o e-mail sai do servidor do seu host. Isso falha nas verificações de SPF e DMARC do domínio do visitante, então o Gmail e o Outlook o tratam como falsificado. Um backend de formulários envia do próprio domínio e coloca o visitante em Reply-To.

### Preciso mudar os nomes dos meus campos?

Não. O Ikiform armazena os nomes que você enviar. Mantenha o campo de e-mail com o nome email, email_address, your_email, reply_to, contact_email, ou adicione um campo _replyto, para que as respostas vão para o visitante.

### O PHPMailer com SMTP é uma opção melhor?

Ele resolve a entregabilidade se você envia por um provedor com o seu domínio configurado para SPF e DKIM. Você ainda precisa de um host PHP, validação, filtro de spam e de um lugar para guardar as mensagens. É uma boa escolha se você já mantém código PHP.

## Mais guias

- [Receber um formulário no e-mail](https://ikiform.com/pt-br/guides/send-form-to-email.md): Receba todo envio de formulário na caixa de entrada sem servidor de e-mail: por que mailto: e mail() do PHP falham, e uma configuração que filtra spam e permite responder.
- [Para o Gmail](https://ikiform.com/pt-br/guides/send-form-to-email/gmail.md): Receba os envios de formulário no Gmail sem links mailto:, senhas de app ou Apps Script, e depois rotule, tire do spam e responda pelo Gmail.
- [Responder pela caixa de entrada](https://ikiform.com/pt-br/guides/send-form-to-email/reply-to.md): Faça o Reply de uma notificação de formulário responder a quem preencheu: quais nomes de campo funcionam, quando usar _replyto e por que as respostas se perdem.
- [Vários destinatários](https://ikiform.com/pt-br/guides/send-form-to-email/multiple-recipients.md): Mande um formulário por e-mail para a equipe toda, ou encaminhe cada mensagem à pessoa certa pelo assunto, sem deixar o próprio formulário escolher quem recebe.
- [Alternativa ao EmailJS](https://ikiform.com/pt-br/guides/send-form-to-email/emailjs-alternative.md): Tire um formulário de contato do EmailJS: por que chaves de e-mail no navegador são um risco, o que muda no seu código e do que você abre mão, como a resposta automática.
- [Next.js](https://ikiform.com/pt-br/guides/send-form-to-email/nextjs.md): Duas formas de mandar um formulário Next.js por e-mail com uma Server Action: enviar você mesmo com Resend ou Nodemailer, ou encaminhar a um backend de formulários, comparadas com honestidade.
