# Como adicionar um formulário de lista de espera a um site no Webflow

> Aponte um Form Block do Webflow para o Ikiform, marque as inscrições pela origem com um campo oculto e mantenha o estado de sucesso do Webflow com um script curto para todos os formulários.

Publicado em 2026-10-25 · https://ikiform.com/pt-br/guides/waitlist/webflow

Mantenha o Form Block que você desenhou no Webflow e mude o action dele para o seu endpoint do Ikiform com o método POST. Adicione um input oculto `ref` e um honeypot num Code Embed, depois cole um script para o site todo que envia cada formulário de lista de espera com `fetch`, preenche `ref` a partir do link e mostra o próprio bloco de sucesso do Webflow com o e-mail da pessoa.

O Webflow é ótimo na página e razoável no formulário. O tratamento nativo de formulários dele armazena os envios e manda e-mail para você, mas limita quantos guarda conforme o plano do site e não consegue marcar uma inscrição com a campanha de onde veio. Um custom action resolve as duas coisas sem sair do Designer.

## O que muda no Webflow

- **Um custom action tira o formulário do Webflow.** O navegador envia direto ao Ikiform, então o Webflow nunca vê a inscrição: ela não fica nos form submissions do Webflow, o Webflow não manda e-mail e ela não usa nada da cota de formulários do seu plano.
- **Os blocos de sucesso e de erro do Webflow param de funcionar.** Eles só aparecem quando o Webflow tratou o envio. Sem um script, os visitantes caem na página de agradecimento do Ikiform ou na URL de **Redirect after submit**.
- **Não existe elemento de input oculto.** Campos ocultos e o honeypot vão num **Code Embed** dentro do formulário, o que exige um plano de site pago, assim como o código personalizado.
- **Nada roda no Designer.** Custom actions e scripts só funcionam no site publicado, então teste no seu domínio de staging `webflow.io`.

Diagrama: Um formulário de lista de espera do Webflow antes e depois de um custom action

1. Por padrão, o Form Block envia ao Webflow, que armazena a inscrição descontando da cota do seu plano e mostra o bloco de sucesso.
2. Com um custom action, o mesmo Form Block aponta para o Ikiform.
3. O script interrompe o envio normal, preenche o campo ref a partir do link e envia com fetch.
4. O Ikiform armazena a inscrição, manda um e-mail para você e envia webhooks, e então responde 201.
5. O script esconde o formulário e mostra o bloco de sucesso do Webflow com o e-mail da pessoa.

O design continua no Webflow. Só muda para onde vão os dados.

## Configure o Form Block

1. Selecione o formulário e abra **Settings**. Remova **Webflow** e **Email notifications** em **Send to**, depois adicione **Custom action**, digite `https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx`, escolha **POST** e salve.
2. Selecione o input de e-mail e defina o **Name** dele como `email`. O Webflow preenche os nomes a partir dos rótulos, então senão você teria `Email` ou `Email 2`, que o Ikiform trata como outro campo.
3. Apague qualquer elemento de reCAPTCHA. O Ikiform não o verifica, e com uma definição de campos o valor `g-recaptcha-response` dele é recusado como campo desconhecido.
4. Arraste um **Code Embed** para dentro do formulário, ao lado do botão, e cole os dois inputs abaixo.
5. Defina **Redirect after submit** nas configurações do formulário no Ikiform com uma página de agradecimento que você publicou no Webflow. É lá que as pessoas caem se o script não rodar.

`Code Embed dentro do formulário`:

```html
<input type="hidden" name="ref" value="webflow">
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
```

Adicione a definição de campos na aba **Fields** do Ikiform, com `email` obrigatório e `ref` como um campo `text` opcional com `max_length` 40. Qualquer outro nome enviado, como um input `Name` esquecido, passa a receber um `422`, o que revela um input com nome errado no primeiro teste.

## O script para o site todo

Cole isto em **Site settings** › **Custom code** › **Footer code**, para que ele cubra o formulário do hero, o do rodapé e qualquer página que você adicionar depois. Ele só mexe em formulários cujo action começa com `https://ikiform.com/f/`.

`Footer code`:

```html
<script>
  const params = new URLSearchParams(location.search);
  const ref = (params.get("ref") || params.get("utm_source") || "").toLowerCase().replace(/[^a-z0-9_-]/g, "").slice(0, 40);
  const key = crypto.randomUUID();

  document.querySelectorAll('form[action^="https://ikiform.com/f/"]').forEach((form, index) => {
    const wrapper = form.closest(".w-form");
    const done = wrapper?.querySelector(".w-form-done");
    const fail = wrapper?.querySelector(".w-form-fail");
    const button = form.querySelector('[type="submit"]');
    const source = form.querySelector('[name="ref"]');
    if (source && ref) source.value = ref;

    form.addEventListener("submit", async (event) => {
      event.preventDefault();
      const label = button.value;
      button.disabled = true;
      button.value = button.dataset.wait || "Joining";
      fail.style.display = "none";
      try {
        const response = await fetch(form.action, {
          method: "POST",
          headers: { Accept: "application/json", "Idempotency-Key": `${key}-${index}` },
          body: new FormData(form),
        });
        const result = await response.json();
        if (result.ok) {
          const email = form.querySelector('[name="email"]').value;
          const line = done.querySelector("div") ?? done;
          line.textContent = `You're on the list. We'll write to ${email} on launch day.`;
          form.style.display = "none";
          done.style.display = "block";
          return;
        }
        const wait = response.headers.get("Retry-After");
        const message = wait ? `Lots of signups right now. Try again in ${wait} seconds.` : result.error.fields?.email?.[0] ?? result.error.message;
        (fail.querySelector("div") ?? fail).textContent = message;
      } catch {
        (fail.querySelector("div") ?? fail).textContent = "Couldn't reach the server. Try again.";
      }
      fail.style.display = "block";
      button.disabled = false;
      button.value = label;
    });
  });
</script>
```

- `?ref=` ou `?utm_source=` no link preenche todos os inputs ocultos `ref` da página. Sem nenhum dos dois, o valor definido no embed é mantido, então defina-o por formulário, como `hero` e `footer`, para ver qual converte.
- A chave de idempotência é criada uma vez por carregamento de página e ganha um sufixo por formulário. Um clique duplo armazena uma única inscrição; uma segunda inscrição em outro formulário da página ainda conta.
- O bloco de sucesso do Webflow ganha uma frase com o e-mail da pessoa, o que pega erros de digitação: as pessoas notam `gmial.com` quando ele é escrito de volta para elas.
- O botão mostra o texto de **Loading** que você definiu no Designer enquanto o envio está em andamento.
- Um `429` mostra quanto tempo esperar, a partir do header `Retry-After` do Ikiform, em vez de uma falha genérica.

> O script envia com `fetch`, então deixe a verificação de spam do formulário desligada. Com a verificação ligada, o Ikiform responde `403 challenge_required` e o bloco de erro aparece. Se você precisa da verificação, dispense o script; o envio simples a roda sem código.

### Domínios permitidos

| Onde o formulário roda | Adicione em Allowed domains |
| --- | --- |
| Staging | `your-site.webflow.io` |
| Seu domínio personalizado | `example.com`, que cobre `www.example.com` |
| O Designer | Nada. Ele nunca envia de lá |

Nunca adicione `webflow.io` sozinho; todo site do Webflow passaria a corresponder. O [guia do Webflow na documentação](https://ikiform.com/pt-br/docs/guides/webflow.md) cobre as mesmas configurações para um formulário de contato, e o [guia principal](https://ikiform.com/pt-br/guides/waitlist.md#confirm) mostra como encaminhar as inscrições para a sua ferramenta de e-mail.

## Confira se funciona

1. Publique no seu domínio de staging `webflow.io`.
2. 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.
3. Abra a página com `?ref=test` e inscreva-se. O bloco de sucesso do Webflow mostra o seu e-mail, e o envio no Ikiform tem `ref` definido como `test`.
4. Inscreva-se de novo pelo formulário do rodapé, sem query string. `ref` mostra o valor do embed desse formulário.
5. Desligue o JavaScript e envie. Você cai na sua página de agradecimento do Webflow.
6. 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`.
7. 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

| Problema | O que fazer |
| --- | --- |
| `404 not_found` depois de enviar | O **Method** é GET, então o navegador abriu o endpoint como um link. Mude para POST e publique de novo. |
| `422` com Unknown field `Email` ou `g-recaptcha-response` | O **Name** de um input não bate com a definição, ou ficou um elemento de reCAPTCHA no formulário. Renomeie o input para `email` ou remova o elemento. |
| O script não faz nada | Você está no Designer, o site não tem plano pago ou o **Action** tem um espaço. Teste no site publicado. |
| `403 challenge_required` | A verificação de spam do formulário está como **Ikiform** e um envio por `fetch` não tinha token. Obtenha um com `challenge(formId)` de `@ikiform/sdk` antes de cada envio, ou desligue a verificação. |
| `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. |

## Perguntas

### As inscrições da lista de espera enviadas ao Ikiform contam no limite de envios de formulário do Webflow?

Não. Com um custom action, o navegador envia direto ao Ikiform, então o Webflow nunca recebe o envio. Ele não aparece nos form submissions do Webflow e não usa a cota do seu plano.

### Como adiciono um campo oculto a um formulário do Webflow?

O Webflow não tem elemento de input oculto. Coloque um Code Embed dentro do formulário com um input do tipo hidden. O Code Embed exige um Site plan pago ou um Workspace Core, Growth, Agency ou Freelancer.

### Posso manter a mensagem de sucesso do Webflow com um custom action?

Sim, com um script. O Webflow só mostra o bloco de sucesso quando tratou o envio, então o script envia com fetch e mostra o bloco ele mesmo, como no exemplo acima.

### O Ikiform pode enviar e-mail para quem preencheu o formulário?

Não. O Ikiform envia e-mail para você e sua equipe, não para quem enviou, então não há resposta automática nem e-mail de confirmação. Envie um webhook para sua ferramenta de e-mail e mande a confirmação de lá.

## Mais guias

- [Lista de espera para um novo SaaS](https://ikiform.com/pt-br/guides/waitlist.md): Monte uma lista de espera pré-lançamento na sua própria landing page: o formulário, proteção contra spam, duplicados, e-mails de confirmação e uma exportação limpa no dia do lançamento.
- [Lista de espera no Framer](https://ikiform.com/pt-br/guides/waitlist/framer.md): Duas formas de coletar inscrições na lista de espera no Framer: o formulário do Framer com webhook para o Ikiform, ou um code component que mantém os limites por visitante e as verificações de spam.
- [Lista de espera no Carrd](https://ikiform.com/pt-br/guides/waitlist/carrd.md): Colete inscrições na lista de espera numa página do Carrd: um formulário Send to URL no Pro Plus com rastreamento de UTM, ou um formulário HTML incorporado com honeypot no Pro Standard.
- [Lista de espera em HTML puro](https://ikiform.com/pt-br/guides/waitlist/html.md): Uma página de lista de espera completa em HTML puro, sem build, que funciona com o JavaScript desligado, mostra um agradecimento na própria página quando carrega e tem plano B quando precisa.
- [Lista para lançamento no Product Hunt](https://ikiform.com/pt-br/guides/waitlist/product-hunt.md): Colete uma lista semanas antes do Product Hunt, marque cada inscrição pelo canal e envie o e-mail do dia do lançamento em duas ondas, no ritmo da virada do horário do Pacífico.
- [Inscrição para beta com triagem](https://ikiform.com/pt-br/guides/waitlist/beta-signup.md): Um formulário de candidatura ao beta com perguntas de triagem que o servidor exige, e um script que pontua os candidatos e escolhe cada turma da lista.
