ID do formulário

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

  1. Adicione o id do formulário

    .env.production
    GATSBY_IKIFORM_FORM_ID=frm_xxxxxxxxxxxxxxxx

    O 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.development para o gatsby develop.

  2. 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 adicione src/pages/thanks.js para 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.

src/api/contact.js
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 rodaAdicione em Allowed domains
gatsby develop e gatsby servelocalhost. Ele corresponde a http://localhost:8000 e http://localhost:9000: o Ikiform compara só o nome do host, nunca a porta.
Seu domínioexample.com, que também cobre www.example.com
Netlifyyour-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 Pagesyour-project.pages.dev. URLs de preview como abc123.your-project.pages.dev são subdomínios dele, então já correspondem.
  • Nunca adicione netlify.app ou pages.dev sozinhos. Todo site naquele host corresponderia, inclusive os de outras pessoas.

Checklist de teste

  1. Rode gatsby build e abra public/contact/index.html. O action do formulário deve terminar no id do seu formulário, não em undefined.
  2. Rode gatsby serve com localhost nos domínios permitidos e envie. A mensagem de agradecimento deve substituir o formulário.
  3. Desative o JavaScript, recarregue e envie. Você deve ver a página de agradecimento do Ikiform localmente, ou /thanks/ no seu domínio https:.
  4. Se você usa a function, envie para /api/contact em 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/undefinedA variável não tem o prefixo GATSBY_, ou não estava definida no buildChame-a de GATSBY_IKIFORM_FORM_ID e gere o build de novo.
A function responde 403 forbiddenA chave secreta é de outro workspace, foi revogada ou não tem submissions:writeCrie uma chave secreta com esse escopo.
/api/contact retorna 404 depois do deployO host só serve arquivos estáticosFaça deploy em um host com Gatsby Functions ou use a versão para navegador.
Os envios chegam no filtro de spam com origin_mismatchA página que enviou não está nos domínios permitidos do formulárioAdicione o host da tabela acima. Com Reject escolhido, os mesmos envios recebem 403 origin_not_allowed.