Guias

Guias18 min de leitura

Formulário de newsletter sem o embed do Mailchimp

Crie um formulário de newsletter no seu próprio markup, registre o consentimento, barre inscrições de bots e passe cada assinante para Kit, MailerLite, beehiiv ou qualquer ferramenta.

Preet SutharFundador, Ikiform

Escreva o formulário de inscrição no seu próprio HTML e aponte-o para um backend de formulários em vez de colar o código de embed do seu provedor de e-mail. O backend valida o endereço e a caixa de consentimento, filtra bots e envia um webhook assinado, e um pequeno relay adiciona o assinante pela API da sua ferramenta de e-mail. A ferramenta de e-mail então envia o e-mail de confirmação, a newsletter e os links de descadastro, então trocar de ferramenta depois significa mudar o relay, não cada formulário.

Toda ferramenta de e-mail oferece um embed: um bloco de markup gerado que você cola na sua página. Funciona, mas o formulário passa a pertencer à ferramenta. Ele envia direto para aquele provedor, carrega o markup do provedor e muitas vezes os estilos e scripts dele, e no dia em que você muda de ferramenta precisa caçar cada cópia dele pelo site. Este guia monta um formulário de inscrição que é seu, no markup e no framework que você já usa, e o conecta à ferramenta que envia a sua newsletter.

Como a inscrição viaja

Há dois trabalhos aqui, e eles ficam em lugares diferentes. Coletar uma inscrição é trabalho de formulário: validar o endereço, conferir a caixa de consentimento, manter os bots fora, registrar quando aconteceu. Enviar uma newsletter é trabalho de e-mail: confirmar o endereço, enviar as edições, cuidar de descadastros e bounces. O Ikiform faz o primeiro. Sua ferramenta de e-mail faz o segundo. Um webhook assinado liga os dois.

Como uma inscrição na newsletter vai da sua página até a sua ferramenta de e-mailseuformuláriode inscriçãorodapé, barralateral ou postIkiformconfereconsentimento espampainelcada inscriçãocom seuconsentimentoe-mail denotificaçãopara você,opcionalwebhookassinadosubmission.createdferramentade e-mailconfirma, envia,descadastraenviorelayComo uma inscrição na newsletter vai da sua página até a sua ferramenta de e-mailseuformuláriodeinscriçãorodapé, barralateral ou postIkiformconfereconsentimentoe spampainelcada inscrição comseu consentimentoe-mail denotificaçãopara você, opcionalwebhookassinadosubmission.createdferramenta dee-mailconfirma, envia,descadastraenviorelay
  1. Um leitor preenche o formulário de inscrição na sua página, e ele envia ao seu endpoint do Ikiform.
  2. O Ikiform confere o endereço, a caixa de consentimento obrigatória, o honeypot, a pontuação de spam e o limite de taxa.
  3. A inscrição aceita é armazenada no painel com data e hora, origem e referrer.
  4. O Ikiform pode avisar você por e-mail a cada inscrição. Ele nunca envia e-mail ao leitor.
  5. O Ikiform envia um webhook submission.created assinado.
  6. Um relay verifica a assinatura e adiciona o leitor à sua ferramenta de e-mail, que envia a confirmação e, depois, cada edição.
O relay é a única parte que sabe qual ferramenta de e-mail você usa. O formulário, o filtro de spam e o registro armazenado não mudam quando a ferramenta muda.

Quatro formas de coletar inscrições na newsletter

AbordagemBom emContras
O embed da ferramenta de e-mail, do Mailchimp, Kit, MailerLite ou beehiivNada para rodar. Confirmação, tags e o e-mail de boas-vindas são configurados nas próprias opções da ferramenta.O markup e o comportamento são da ferramenta. O Mailchimp avisa que seus formulários incorporados herdam os estilos do seu site, então podem ficar diferentes na sua página, e ligar o reCAPTCHA dele num formulário existente significa gerar e colar um código novo. Cada cópia fica presa a um provedor.
Sua própria rota no servidor que chama a API da ferramentaControle total do formulário e da requisição, com a chave de API guardada no seu servidor.Você mesmo constrói a validação, o filtro de bots, os limites de taxa e o registro de consentimento, e precisa de um servidor mesmo que o site seja estático.
Um criador de formulários hospedado mais uma automação, como Typeform com ZapierNenhum código, e a ferramenta de automação conhece todo provedor de e-mail.Um iframe que não combina com a sua página, mais duas assinaturas. Webhooks e marca dependem do plano.
Um backend de formulários, como o Ikiform, mais um relaySeu próprio markup em qualquer site, filtro de spam, um registro de consentimento armazenado e webhooks assinados, sem servidor para o formulário.O Ikiform não envia e-mail ao leitor. A confirmação e cada newsletter saem da sua ferramenta de e-mail, por um pequeno relay ou uma automação.

Está feliz com um site, uma ferramenta e o embed dela? Mantenha. Construa o seu quando o formulário precisar combinar com o seu design, estiver em vários sites ou puder durar mais que a ferramenta.

O formulário

Um bom formulário de newsletter é pequeno: um e-mail, um primeiro nome opcional para a saudação e uma caixa de consentimento cujo rótulo é a promessa que você está fazendo. Um input oculto source registra em que lugar do site a inscrição aconteceu. Escolha sua stack; a escolha vale para todos os exemplos de código destes guias.

Cole o formulário no rodapé, na barra lateral ou no fim de um post. Ele envia do jeito tradicional e cai na sua própria página de agradecimento, então funciona sem JavaScript.

footer.html
<form id="newsletter" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label for="nl-email">Email</label>
  <input id="nl-email" name="email" type="email" required autocomplete="email" placeholder="you@example.com" />

  <label for="nl-name">First name (optional)</label>
  <input id="nl-name" name="first_name" type="text" maxlength="80" autocomplete="given-name" />

  <label>
    <input name="consent" type="checkbox" value="true" required />
    Email me the newsletter. I can unsubscribe at any time.
  </label>

  <input type="hidden" name="source" value="footer" />
  <input type="hidden" name="_redirect" value="https://example.com/subscribed" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />

  <button>Subscribe</button>
  <p id="nl-status" role="status" hidden></p>
</form>

Para manter o leitor no artigo, adicione este script depois do formulário. Ele envia com fetch, troca o formulário por uma frase pedindo para conferir a caixa de entrada e mostra a mensagem do servidor para o e-mail ou a caixa de seleção.

newsletter.js
const form = document.querySelector("#newsletter");
const status = document.querySelector("#nl-status");
const button = form.querySelector("button");

form.addEventListener("submit", async (event) => {
  event.preventDefault();
  const body = new FormData(form);
  button.disabled = true;
  status.hidden = false;
  status.textContent = "Subscribing";
  try {
    const response = await fetch(form.action, { method: "POST", headers: { Accept: "application/json" }, body });
    const result = await response.json();
    if (result.ok) {
      form.replaceChildren(status);
      status.textContent = "Almost done. Open the email we sent you and confirm your address.";
      return;
    }
    const fields = result.error.fields ?? {};
    status.textContent = fields.email?.[0] ?? fields.consent?.[0] ?? result.error.message;
  } catch {
    status.textContent = "Couldn't reach the server. Try again.";
  }
  button.disabled = false;
});
  • Troque frm_xxxxxxxxxxxxxxxx pelo id do seu formulário, que está no painel.
  • Mantenha o name do input de e-mail como email. O Ikiform o valida, coloca o domínio em minúsculas e o confere contra domínios de e-mail descartáveis.
  • O input oculto _gotcha é o honeypot. Pessoas nunca o veem, e bots que preenchem todo input se marcam como spam.
  • A caixa de seleção envia true quando marcada. Desmarcada, não envia nada, e uma caixa obrigatória é recusada com This box must be checked.
  • A frase de sucesso pede para conferir a caixa de entrada, porque sua ferramenta de e-mail envia uma confirmação. Se você desligou o double opt-in, troque por um simples obrigado.
  • As versões no servidor repassam o header Origin do navegador, porque o Ikiform reconhece por ele os testes gratuitos em localhost e o fetch do próprio servidor não envia nenhum.
As versões no servidor enviam com uma chave secreta, então o Ikiform pula Allowed domains e a verificação humana. Todo envio passa a vir do IP do seu servidor, e o limite Standard de 5 por minuto por visitante conta todos os seus visitantes juntos. Escolha o limite de taxa Relaxed ou Custom para um formulário que você envia por um servidor, e mantenha IKIFORM_SECRET_KEY em variáveis de ambiente só do servidor.

A configuração de cada framework está na documentação: Next.js, Astro, SvelteKit, Nuxt, React, Vue e HTML simples. O modelo de formulário de newsletter gera os mesmos campos em HTML, React e uma server action do Next.js.

Campos e a definição

Cole a definição abaixo na aba Fields do formulário e o Ikiform a aplica no servidor, não importa o que a página envie. A prévia roda o mesmo validador no seu navegador: deixe a caixa desmarcada e envie para ver o erro que um bot ou uma página quebrada receberia.

Prévia

Roda o validador do Ikiform no seu navegador. Nada é enviado.

Na sua página, source é um input oculto. Aqui ele é um campo de texto visível só para você poder testar.
CampoPor quêLembre-se
emailO assinanteObrigatório. type="email" abre o teclado certo no celular
first_nameUma saudação em cada ediçãoOpcional. A maioria das ferramentas de e-mail tem um campo de primeiro nome para mapeá-lo
consentUm registro de que a pessoa pediu os e-mailsCaixa de seleção obrigatória. Armazenada como true
sourceQual formulário do site funcionou: rodapé, post, popupOculto. Use um valor diferente por posição e repasse-o como tag ou campo

Com os campos definidos, o Ikiform recusa qualquer input que não conhece com unknown_field, então adicione o campo à definição antes de adicionar o input à página. Nomes que começam com _, como _redirect, são instruções para o Ikiform e nunca contam como campos.

Uma newsletter é um e-mail que alguém pediu. A caixa de seleção deixa o pedido explícito, e o envio armazenado o registra. É isto que o Ikiform guarda para cada inscrição aceita:

data.fields
{
  "email": "ada@example.com",
  "first_name": "Ada",
  "consent": true,
  "source": "footer"
}

Além dos campos, cada envio tem o timestamp created_at, a origem e o referrer da página, o país e o user agent do navegador. Juntos, mostram quando e onde a pessoa marcou a caixa. Dois hábitos tornam esse registro útil depois:

  1. Escreva o rótulo como a promessa. "Quero receber a newsletter por e-mail. Posso cancelar a inscrição a qualquer momento." diz o que a pessoa recebe. Se você também envia ofertas, diga isso no rótulo.
  2. Anote a data quando o texto mudar. Um true armazenado diz que a pessoa concordou, não com qual texto. Mantenha um pequeno histórico do rótulo com datas, para que cada inscrição possa ser ligada às palavras que viu.

O Ikiform guarda o registro; ele não sabe dizer o que as regras do lugar onde você e seus leitores vivem exigem. Confira isso com alguém que as conheça.

Os e-mails de confirmação saem da sua ferramenta de e-mail

O Ikiform não envia e-mail para quem preenche o formulário. Os e-mails de notificação vão só para você e sua equipe, então não há resposta automática, e-mail de confirmação nem double opt-in. Envie esses e-mails pela sua ferramenta de e-mail, disparados por um webhook. Essa divisão é proposital. A ferramenta que envia sua newsletter já registra quem confirmou, quem se descadastrou e quais endereços dão bounce. Se um segundo sistema enviasse as confirmações, esses registros sairiam de sincronia.

Por isso o relay adiciona o leitor num estado que faz a ferramenta de e-mail enviar a própria confirmação, e a ferramenta o marca como ativo quando ele clica. Cada ferramenta liga isso de um jeito: uma opção do formulário, uma chave da conta ou uma flag na requisição da API. O guia de double opt-in cobre os três, e o que acontece quando um assinante conhecido se inscreve de novo.

O relay

Um relay é uma função curta que recebe o webhook do Ikiform, confere a assinatura e chama a API da sua ferramenta de e-mail. Ele precisa de uma URL HTTPS pública e de um segredo de cada lado. Este é um route handler do Next.js; o mesmo código roda em qualquer runtime com fetch.

app/api/newsletter/route.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { addSubscriber } from "@/lib/email-tool";

export async function POST(request: Request) {
  const payload = await request.text();
  let event;
  try {
    event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.IKIFORM_WEBHOOK_SECRET! });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
  if (event.type !== "submission.created") return new Response(null, { status: 204 });

  const fields = event.data.fields;
  if (fields.consent !== true) return new Response("No consent, skipped", { status: 200 });

  const answer = await addSubscriber({
    email: String(fields.email),
    firstName: typeof fields.first_name === "string" ? fields.first_name : undefined,
    source: typeof fields.source === "string" ? fields.source : "unknown",
    referrer: typeof event.data.meta.referrer === "string" ? event.data.meta.referrer : undefined,
  });
  if (answer.status === 429) {
    return new Response("Email tool rate limit", {
      status: 503,
      headers: { "retry-after": answer.headers.get("retry-after") ?? "60" },
    });
  }
  if (!answer.ok) return new Response(`Email tool answered ${answer.status}`, { status: 502 });
  return new Response(null, { status: 204 });
}
  • verifyWebhook confere a assinatura HMAC e o timestamp. Sem ele, qualquer um que descubra a URL pode adicionar endereços à sua lista.
  • Eventos endpoint.test, do Send test no painel, são respondidos com 204 e ignorados.
  • A checagem de consentimento é uma segunda trava atrás da definição do formulário.
  • addSubscriber é a única parte que depende da ferramenta. O corpo dela para cada ferramenta está nas páginas de Kit, MailerLite e beehiiv.

O que o relay responde decide o que o Ikiform faz em seguida:

O que o relay responde ao Ikiform para cada resposta da ferramenta de e-mail200 ou 201adicionado ou atualizado204sem conteúdoprontoentrega bem-sucedida429limite de taxa503com Retry-Afteresperae tenta de novo4xx ou 5xxrecusado ou fora do ar502com o status daferramentatenta de novomesmo webhook-idferramenta de e-mailresponderelay respondeIkiformO que o relay responde ao Ikiform para cada resposta da ferramenta de e-mail200 ou201adicionadoouatualizado204semconteúdoprontoentregabem-sucedida429limite detaxa503comRetry-Afteresperae tentade novo4xx ou5xxrecusadoou forado ar502com ostatus daferramentatentade novomesmowebhook-idferramentade e-mailresponderelayrespondeIkiform
  1. A ferramenta de e-mail adiciona ou atualiza o assinante: o relay responde 204 e a entrega é marcada como bem-sucedida.
  2. A ferramenta de e-mail está com limite de taxa: o relay responde 503 com Retry-After, e o Ikiform espera esse tempo antes da próxima tentativa.
  3. A ferramenta de e-mail recusa a requisição ou está fora do ar: o relay responde 502, e o Ikiform tenta de novo no seu cronograma com o mesmo webhook-id.
Cada tentativa fica no log de entregas do endpoint com a resposta do seu relay, então um 502 que cita o status da ferramenta diz o que corrigir.

Adicione a URL do relay em Webhooks no painel, escolha o formulário da newsletter e copie o segredo whsec_ para IKIFORM_WEBHOOK_SECRET. Um workspace tem até 3 endpoints. A URL precisa ser HTTPS pública na porta 443; hostnames workers.dev e pages.dev são recusados, então dê um domínio personalizado ao Worker. Tentativas, payloads e o esquema de assinatura estão na documentação de webhooks, e envios de formulário para o seu próprio servidor tem uma versão que armazena cada entrega uma única vez.

Sem código? Aponte o webhook para uma ferramenta de automação e use a ação dela para a sua ferramenta de e-mail em vez de um relay. Veja Zapier, Make ou n8n. Não há integrações de um clique. Toda ferramenta é alcançada por um webhook assinado, diretamente ou por uma ferramenta de automação como Zapier ou n8n.

Mantenha bots e list bombing longe

Inscrições de bots prejudicam mais uma newsletter do que a maioria dos formulários. Um endereço real inscrito por um bot recebe e-mails que nunca pediu, e reclamações dessas pessoas prejudicam o domínio de onde você envia. Alguns bots inscrevem o endereço de uma vítima em centenas de formulários de uma vez para soterrar a caixa de entrada dela, e todo formulário com e-mail de confirmação participa disso.

DefesaO que ela barraConfiguração
HoneypotBots que preenchem todos os inputsO input oculto _gotcha
Consentimento obrigatórioScripts que enviam só um e-mailA caixa de seleção consent com required: true na definição
Pontuação de spamEndereços descartáveis (+2), repetições idênticas (+3), links e frases de spam. Com 5, a inscrição é armazenada como spamNenhuma
Limites de taxaUm visitante enviando em loopLigado por padrão: Standard, 5 por minuto por visitante
Verificação humanaBots que rodam um navegador de verdadeDefina Spam check como Ikiform para usar o Cloudflare Turnstile sem chaves para gerenciar
Domínios permitidosO endpoint do seu formulário copiado em outros sitesListe todo domínio em que o formulário aparece

Spam recebe a mesma resposta de sucesso que uma inscrição real e não envia webhook, então nunca chega à sua ferramenta de e-mail nem dispara um e-mail de confirmação. Se um leitor real cair em spam, marque como não spam e o webhook dele sai nesse momento. A documentação de spam explica cada checagem e sua pontuação.

Um limite por visitante rígido combina com um formulário de newsletter, porque a pessoa se inscreve uma vez. Se o seu público lê de escritórios ou campi que compartilham um IP, o Standard os conta juntos; ali, Relaxed, com 20 por minuto por visitante, é a escolha mais segura. Veja limites de taxa.

Um formulário em muitas páginas

Um endpoint pode ficar no rodapé de toda página, no fim de cada post e numa página /newsletter. Dê a cada posição seu próprio valor de source para saber qual traz inscrições:

  • footer: visto em toda página. Deixe só o e-mail e a caixa de seleção.
  • post: leitores que terminaram um artigo, muitas vezes os que mais convertem.
  • newsletter-page: para onde os perfis sociais apontam. Espaço para uma edição de exemplo.

Cada envio também registra o referrer, que é a página exata em que o leitor estava, então source diz a posição e o referrer diz o artigo. Adicione cada domínio que mostra o formulário em Allowed domains, até 20 por formulário; subdomínios de um domínio listado são permitidos automaticamente.

O mesmo leitor duas vezes

O Ikiform não mescla nem rejeita envios repetidos por e-mail. Uma repetição idêntica dentro de 24 horas só soma à pontuação de spam. Remova duplicados onde a lista mora, ou na exportação. Para uma newsletter isso raramente é problema: Kit, MailerLite e beehiiv identificam os assinantes pelo e-mail, então uma repetição atualiza um contato em vez de criar um segundo.

Trocar de ferramenta de e-mail depois

É aqui que ser dono do formulário compensa. Mudar de uma ferramenta de e-mail para outra normalmente significa trocar cada embed do site. Aqui o formulário não sabe qual ferramenta está por trás dele:

O que muda quando você passa para outra ferramenta de e-mailcom um embedcom seu formuláriotoda páginacódigo de embedcoladoferramentaantigaformulário enviaaquiferramenta novanovo embed em todapáginatoda páginaigualIkiformigualrelayuma função mudaenviotrocar tudoenviowebhookO que muda quando você passa para outra ferramenta de e-mailcom um embedcom seu formuláriotoda páginacódigo de embed coladoferramenta antigaformulário envia aquiferramenta novanovo embed em toda páginatoda páginaigualIkiformigualrelayuma função mudaenviotrocar tudoenviowebhook
  1. Com um embed, toda página carrega código que envia direto para a ferramenta antiga, então mudar significa trocar cada cópia.
  2. Com o seu próprio formulário, toda página continua enviando ao Ikiform, e o Ikiform continua enviando o mesmo webhook.
  3. Só a função addSubscriber do relay muda, para chamar a API da nova ferramenta.
Se quiser, rode as duas ferramentas por uma semana: dois endpoints de webhook, dois relays, um formulário. Depois remova o endpoint antigo.

Migre os assinantes existentes com a exportação da própria ferramenta antiga, já que só ela sabe quem confirmou e quem saiu. A exportação CSV do Ikiform, de até 100.000 linhas por arquivo, serve para conferir os números, não para importar.

Escolha o seu caso

O formulário acima é o mesmo em todo lugar. Estas páginas cobrem e-mails de confirmação, sites sem servidor e as chamadas exatas de API para três ferramentas de e-mail.

Confira se funciona

Repasse isto antes de adicionar o formulário a toda página. O Ikiform não tem plano gratuito. Testar é gratuito: um workspace sem plano aceita 50 envios de teste por mês a partir de localhost. Para entrar no ar, escolha o Pro a partir de US$ 6/mês para 500 envios, ou pague uma vez: 10.000 envios por US$ 49 ou 50.000 envios por US$ 149, com créditos que nunca expiram. Veja preços.

  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 com a caixa desmarcada pelas ferramentas de desenvolvedor do navegador, ou remova o required por um momento. Você recebe 422 com This box must be checked e nada é armazenado.
  3. Envie direito, com um endereço seu. Você vê a frase pedindo para conferir a caixa de entrada, ou cai na sua página de agradecimento.
  4. Abra Submissions no painel. O novo envio está lá com todos os campos que você enviou.
  5. Abra o endpoint em Webhooks. A entrega mostra succeeded e a resposta do seu relay.
  6. Abra sua ferramenta de e-mail. O assinante está lá, não confirmado se o double opt-in estiver ligado, e o e-mail de confirmação está na sua caixa de entrada.
  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.
  8. Não chegou nada? Mude o filtro de status do painel para Spam. Spam recebe a mesma resposta de sucesso de um envio real.

Solução de problemas

ProblemaO que fazer
422 validation_failed com consentA caixa não foi marcada, ou o name do input não é consent. Uma versão no servidor precisa enviar true, "true" ou "on"; uma caixa desmarcada não envia nada.
422 validation_failed com unknown_fieldA página envia um input que a definição não lista, muitas vezes um source oculto ou um input de rastreamento adicionado depois. Adicione-o à definição ou remova o input.
403 origin_not_allowed, ou todo envio cai no spamO 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.
429 rate_limitedUm visitante enviou mais do que o limite de taxa do formulário permite. O Standard permite 5 por minuto por visitante. Espere o Retry-After, ou escolha Relaxed ou Custom para formulários que enviam a partir de um único IP compartilhado.
O envio está no painel, mas nenhum e-mail ou webhook chegouEle 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.
As inscrições chegam no Ikiform, mas não na ferramenta de e-mailLeia o log de entregas em Webhooks. 400 significa que o segredo do relay está errado. 502 traz o status da ferramenta de e-mail: geralmente uma chave de API, id de lista ou id de formulário errado.
O assinante está na ferramenta de e-mail, mas não recebeu e-mail de confirmaçãoO double opt-in está desligado na ferramenta, ou o relay criou o assinante como já confirmado. Veja double opt-in para a chave de cada ferramenta.
O navegador cai na página de agradecimento do Ikiform em vez da suaO _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.

Perguntas

Travou em algum passo ou quer um guia para o seu caso? Envie um e-mail para hello@ikiform.com.