Gatsby
Um formulário Gatsby que já funciona no HTML estático antes da hidratação, aprimorado com fetch depois, mais uma Gatsby Function para envios com chave secreta.
O Gatsby renderiza cada página em HTML no build. Dê ao formulário um action de verdade e ele envia antes de o React hidratar, ou se o bundle não carregar; depois da hidratação, o componente envia com fetch e mostra o resultado no lugar.
Envie a partir do navegador
Adicione o id do formulário
.env.production GATSBY_IKIFORM_FORM_ID=frm_xxxxxxxxxxxxxxxxO Gatsby só expõe ao código do navegador as variáveis que começam com
GATSBY_, e as incorpora no build. Adicione a mesma linha em.env.developmentpara ogatsby develop.Adicione o componente
src/components/contact-form.js import * as React from "react"; const endpoint = `https://ikiform.com/f/${process.env.GATSBY_IKIFORM_FORM_ID}`; export default function ContactForm() { const [status, setStatus] = React.useState("idle"); const [message, setMessage] = React.useState(""); async function onSubmit(event) { event.preventDefault(); setStatus("sending"); try { const response = await fetch(endpoint, { method: "POST", headers: { Accept: "application/json" }, body: new FormData(event.currentTarget), }); const result = await response.json(); if (result.ok) return setStatus("sent"); setMessage(result.error.message); } catch { setMessage("Couldn't reach the server. Try again."); } setStatus("error"); } if (status === "sent") return <p>Thanks, we got it.</p>; return ( <form action={endpoint} method="post" onSubmit={onSubmit}> <label> Email <input name="email" type="email" autoComplete="email" required /> </label> <label> Message <textarea name="message" rows={5} /> </label> <input type="hidden" name="_redirect" value="https://example.com/thanks/" /> <input name="_gotcha" type="text" tabIndex={-1} autoComplete="off" hidden /> {status === "error" ? <p role="alert">{message}</p> : null} <button disabled={status === "sending"}>Send</button> </form> ); }Renderize-o em qualquer página, por exemplo
src/pages/contact.js, e adicionesrc/pages/thanks.jspara o redirecionamento sem JavaScript. Para erros de campo e a verificação humana do SDK, estenda-o como no guia de React.
Envie a partir de uma Gatsby Function
Uma Gatsby Function pode repassar o envio com uma chave secreta, o que pula os domínios permitidos e a verificação humana. Ela só roda em hosts que suportam Gatsby Functions, como a Netlify com o adapter do Gatsby; um host puramente estático como o GitHub Pages não consegue rodá-la. Guarde IKIFORM_FORM_ID e uma chave secreta com o escopo submissions:write como IKIFORM_SECRET_KEY, sem o prefixo GATSBY_, para que nunca cheguem ao navegador.
export default async function handler(req, res) {
if (req.method !== "POST") return res.status(405).end();
const response = await fetch(`https://ikiform.com/f/${process.env.IKIFORM_FORM_ID}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${process.env.IKIFORM_SECRET_KEY}`,
},
body: JSON.stringify(req.body),
});
res.status(response.status).json(await response.json());
}O Gatsby converte corpos JSON e form-encoded em req.body, então a página pode enviar para /api/contact de qualquer forma. Todos os envios passam a compartilhar o endereço IP da sua function nos limites de taxa; veja A partir de um servidor.
Domínios permitidos
Isto vale para envios pelo navegador. Envios pela Gatsby Function usam uma chave secreta e pulam a verificação.
| Onde o formulário roda | Adicione em Allowed domains |
|---|---|
gatsby develop e gatsby serve | localhost. Ele corresponde a http://localhost:8000 e http://localhost:9000: o Ikiform compara só o nome do host, nunca a porta. |
| Seu domínio | example.com, que também cobre www.example.com |
| Netlify | your-site.netlify.app. Deploy previews (deploy-preview-12--your-site.netlify.app) e branch deploys (branch--your-site.netlify.app) não são subdomínios dele, então adicione o host exato do preview enquanto testa um. |
| Cloudflare Pages | your-project.pages.dev. URLs de preview como abc123.your-project.pages.dev são subdomínios dele, então já correspondem. |
- Nunca adicione
netlify.appoupages.devsozinhos. Todo site naquele host corresponderia, inclusive os de outras pessoas.
Checklist de teste
- Rode
gatsby builde abrapublic/contact/index.html. Oactiondo formulário deve terminar no id do seu formulário, não emundefined. - Rode
gatsby servecomlocalhostnos domínios permitidos e envie. A mensagem de agradecimento deve substituir o formulário. - Desative o JavaScript, recarregue e envie. Você deve ver a página de agradecimento do Ikiform localmente, ou
/thanks/no seu domíniohttps:. - Se você usa a function, envie para
/api/contactem um deploy preview e confirme que o envio aparece no Ikiform.
Solução de problemas
| O que você vê | Por quê | Correção |
|---|---|---|
404 not_found, e o action termina em /f/undefined | A variável não tem o prefixo GATSBY_, ou não estava definida no build | Chame-a de GATSBY_IKIFORM_FORM_ID e gere o build de novo. |
A function responde 403 forbidden | A chave secreta é de outro workspace, foi revogada ou não tem submissions:write | Crie uma chave secreta com esse escopo. |
/api/contact retorna 404 depois do deploy | O host só serve arquivos estáticos | Faça deploy em um host com Gatsby Functions ou use a versão para navegador. |
Os envios chegam no filtro de spam com origin_mismatch | A página que enviou não está nos domínios permitidos do formulário | Adicione o host da tabela acima. Com Reject escolhido, os mesmos envios recebem 403 origin_not_allowed. |