Formulário de contato em site estático7 min de leitura
Adicione um formulário de contato a um site no GitHub Pages
O GitHub Pages não roda código de servidor, então um POST de formulário recebe 405 Not Allowed; envie para um backend de formulários e acerte os redirecionamentos de project sites.
O GitHub Pages só serve arquivos estáticos, então um formulário que envia para o seu próprio site recebe 405 Not Allowed e a mensagem se perde. Defina o action do formulário como um endpoint do Ikiform, adicione username.github.io e qualquer domínio personalizado em Allowed domains e redirecione para uma página de agradecimento que inclua o caminho do seu project site. Nada muda no seu repositório nem nas configurações do Pages, e nenhum segredo vai parar no repositório público.
O que muda no GitHub Pages
O GitHub Pages publica o que o seu repositório ou o seu workflow do Actions gera, e nada além disso. O Jekyll roda no build se você o usa, e o resultado são arquivos. Não existe handler de requisições, então o mail() do PHP, um script Node ou um formulário CGI em Python não vão rodar, faça o commit que fizer.
Dá para ver a falha pelo terminal. Um POST para qualquer página de um site no Pages recebe isto:
curl -i -X POST -d "message=hello" https://ada.github.io/notebook/contact.htmlHTTP/2 405
server: Varnish
content-length: 131
<html>
<head><title>405 Not Allowed</title></head>Mais quatro coisas diferenciam o Pages de outros hosts estáticos, e cada uma afeta o formulário de contato:
| Característica do Pages | O que significa para o formulário |
|---|---|
Project sites ficam sob um caminho, username.github.io/repo/ | Uma URL de agradecimento /thanks.html aponta para o user site, não para o seu projeto. Toda URL precisa da parte /repo/ |
| Nenhuma configuração para headers de resposta personalizados | Uma Content-Security-Policy só pode vir de uma tag <meta> na página |
| O repositório muitas vezes é público | Tudo nele é público. O id do formulário pode ficar lá; uma chave de API secreta ou uma senha de e-mail, nunca |
| O GitHub diz que sites do Pages não devem ser usados para transações sensíveis, como enviar senhas ou números de cartão de crédito | Deixe o formulário de contato ser só um formulário de contato. Não colete dados de cartão nem senhas de conta por ele |
- Você faz push para a branch de onde o Pages publica.
- O Jekyll ou o seu workflow do Actions gera o site uma vez.
- O Pages serve o resultado como arquivos estáticos no github.io ou no seu domínio personalizado.
- Um visitante envia o formulário de contato. Se o action dele aponta para o seu próprio site, o Pages responde 405 Not Allowed.
- Com o action definido como o seu endpoint do Ikiform, o Ikiform armazena a mensagem e manda um e-mail para você.
- O Ikiform redireciona o navegador para a página de agradecimento, que o Pages serve como qualquer outro arquivo.
O formulário
Para um site escrito à mão, adicione contact.html ao lado do index.html. Este é para um project site em ada.github.io/notebook, então o redirecionamento inclui /notebook/:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; form-action 'self' https://ikiform.com; connect-src 'self' https://ikiform.com"
/>
<title>Contact</title>
</head>
<body>
<h1>Get in touch</h1>
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<label for="name">Name</label>
<input id="name" name="name" autocomplete="name" required />
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="about">What is it about?</label>
<select id="about" name="about">
<option value="question">A question about the project</option>
<option value="hire">Work together</option>
<option value="other">Something else</option>
</select>
<label for="message">Message</label>
<textarea id="message" name="message" rows="6" minlength="10" required></textarea>
<input type="hidden" name="page" value="docs-home" />
<input type="hidden" name="_redirect" value="https://ada.github.io/notebook/thanks.html" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button type="submit">Send</button>
</form>
</body>
</html>- A Content-Security-Policy via
<meta>é opcional. Mantenha-a se você já tem uma, e garanta queform-actioneconnect-srcincluamhttps://ikiform.com. O Pages não consegue enviar o header por você. - O select
aboutdiz por que alguém escreveu antes de você abrir a mensagem. Troque as opções pelos assuntos sobre os quais as pessoas realmente escrevem para você. - O input oculto
pageregistra em que página o formulário estava, o que é útil quando o mesmo formulário aparece em várias páginas da documentação. - Mantenha
emailcomo nome do campo. Os e-mails de notificação o usam como endereço de reply-to.
Se o mesmo HTML é publicado em vários caminhos, ou se você não tem certeza de qual será o caminho final, monte o redirecionamento no navegador a partir do próprio endereço da página. Coloque isto depois do formulário:
<script>
document.querySelectorAll('input[name="_redirect"]').forEach((input) => {
input.value = new URL("thanks.html", document.baseURI).href;
});
</script>Usa Jekyll? Não escreva a URL fixa. O guia do Jekyll tem um include que a monta com absolute_url, que adiciona o seu baseurl para project sites. Gera com Astro, Vite ou Hugo por um workflow do Actions? Defina o base path do framework como /repo/ para os assets do formulário carregarem, e use o guia do Hugo ou do framework para o formulário em si.
Domínios permitidos no github.io
Adicione ada.github.io, com o seu próprio nome de usuário. Ele cobre o seu user site e todos os project sites, porque os project sites compartilham o mesmo host. Adicione também o seu domínio personalizado, se usar um; example.com também cobre www.example.com.
Nunca adicione github.io sozinho. Todo site do Pages passaria a corresponder, inclusive cópias do seu formulário em sites de outras pessoas. Com domínios permitidos definidos, um _redirect para https://ada.github.io/notebook/thanks.html é seguido; sem eles, o Ikiform o ignora e mostra a página de agradecimento hospedada.
_redirect que começam com https:, e um domínio personalizado ainda sem certificado serve páginas http:.Substituindo um link mailto:
Muitos sites no Pages começam com um link mailto: no rodapé. Trocá-lo pelo formulário impede que novos scrapers leiam seu endereço na página, e visitantes sem app de e-mail configurado finalmente conseguem falar com você. Duas coisas a saber antes de apagá-lo:
- O endereço continua no histórico do seu repositório e em qualquer fork ou arquivo da página antiga. O formulário ajuda daqui para frente; ele não torna privado de novo um endereço que ficou público por anos.
- As respostas saem da sua própria caixa de entrada. Os e-mails de notificação definem o remetente como endereço de reply-to, então clicar em Reply funciona como o link
mailto:funcionava, só que do outro lado.
O Ikiform nunca envia e-mail ao visitante, então diga na página de agradecimento quando ele pode esperar uma resposta. Se você recebe mais mensagens do que consegue responder por e-mail, um webhook pode jogar cada uma no Slack ou no Discord.
Confira se funciona
Faça isto no endereço github.io publicado. O Pages não tem deploys de preview, então teste antes localmente com um servidor local.
- Adicione
localhosteusername.github.ioem Allowed domains, mais o seu domínio personalizado, se tiver um. - Faça commit de
contact.htmlethanks.html, espere o deploy do Pages terminar na aba Actions do repositório e abra a página publicada. - Envie o formulário. Você deve cair no seu próprio
thanks.html, com o caminho do projeto na barra de endereço. - Abra Submissions no painel. O novo envio está lá com todos os campos que você enviou.
- 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. - Não chegou nada? Mude o filtro de status do painel para Spam. Spam recebe a mesma resposta de sucesso de um envio real.
Pegadinhas
| Problema | O que fazer |
|---|---|
405 Not Allowed depois de clicar em Enviar | O formulário publicado ainda envia para o seu próprio site. Veja o código-fonte da página no github.io e confira o action; um build antigo em cache pode continuar no ar por alguns minutos. |
| A página de agradecimento do Ikiform em vez da sua | O valor de _redirect está sem o caminho do repositório, é http:, ou o formulário não tem domínios permitidos. Adicione username.github.io e use a URL https: completa. |
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. |
| Os envios funcionam localmente, mas o console mostra um erro de CSP no github.io | Uma Content-Security-Policy via <meta> no seu layout não tem https://ikiform.com em form-action ou connect-src. |
Perguntas
Não. O GitHub Pages serve arquivos estáticos e não roda nenhum código quando um visitante envia um formulário, então um POST para uma URL do Pages recebe 405 Not Allowed. Aponte o action do formulário para um backend de formulários.
Sim. O id do formulário acaba no seu HTML público de qualquer forma. Proteja o formulário com domínios permitidos e as verificações de spam, e nunca faça commit de uma chave de API secreta, porque um site estático não tem um lugar seguro para guardá-la.
Um caminho como /thanks.html aponta para a raiz de username.github.io, não para o seu projeto. Use a URL completa com o caminho do repositório, ou monte-a a partir de document.baseURI no navegador.
Sim. O formulário envia ao Ikiform seja qual for o domínio que serve a página. Adicione o domínio personalizado em Allowed domains ao lado de username.github.io, e atualize qualquer valor de _redirect para usar o domínio personalizado quando o HTTPS estiver ativado.
Não, não há plano gratuito. Testar é grátis: você pode enviar 50 envios de teste por mês a partir de localhost antes de pagar. Para entrar no ar, o Pro começa em US$ 6/mês para 500 envios, ou você pode pagar uma vez 10.000 envios por US$ 49 ou 50.000 envios por US$ 149, com créditos que nunca expiram.
Travou em algum passo ou quer um guia para o seu caso? Envie um e-mail para hello@ikiform.com.