Formulaire d'inscription à la newsletter

Formulaire d'inscription à la newsletter7 min de lecture

Le double opt-in pour un formulaire de newsletter que vous avez créé vous-même

Ikiform n'envoie pas d'e-mails de confirmation : le double opt-in se fait donc dans votre outil d'e-mailing. Un relais ajoute chaque inscription comme non confirmée et l'outil envoie le lien.

Preet SutharFondateur, Ikiform

Ikiform n'écrit jamais à la personne qui s'inscrit : l'e-mail de confirmation doit donc venir de l'outil qui envoie votre newsletter. Un relais reçoit le webhook signé d'Ikiform et ajoute le lecteur à cet outil comme non confirmé, l'outil lui envoie un lien, et seul un clic en fait un abonné. Chaque outil active cela différemment, et le relais ne doit jamais envoyer une seconde confirmation à quelqu'un qui est déjà abonné.

Ce qui change ici

Ikiform n'envoie pas d'e-mail à la personne qui remplit le formulaire. Les e-mails de notification vont uniquement à vous et à votre équipe : il n'y a donc ni réponse automatique, ni e-mail de confirmation, ni double opt-in. Envoyez-les depuis votre outil d'e-mailing, déclenché par un webhook. Avec l'embed d'un fournisseur, la confirmation est un réglage du formulaire du fournisseur. Avec votre propre formulaire, deux systèmes interviennent, et la confirmation revient à celui qui gère la liste. Le travail consiste à s'assurer que chaque inscription arrive dans cet outil dans un état qui déclenche sa confirmation, et n'en déclenche pas quand elle ne doit pas.

Le double opt-in est une machine à états dans l'outil d'e-mailing. Le lecteur commence non confirmé, ne peut pas recevoir de numéros, et ne devient abonné que lorsqu'il clique. Le rôle d'Ikiform s'arrête quand le relais répond 204.

La vie d'une inscription en double opt-in, du formulaire à l'abonné confirméformulaireconsentementcochéIkiformstocke, signele webhookrelaisajoute en nonconfirméoutild'e-mailingenvoie le lienconfirméreçoit chaquenuméropas de clicreste nonconfirmé,aucun numéroenvoiwebhookAPIclicLa vie d'une inscription en double opt-in, du formulaire à l'abonné confirméformulaireconsentement cochéIkiformstocke, signe lewebhookrelaisajoute en non confirméoutil d'e-mailingenvoie le lienconfirméreçoitchaquenuméropas declicreste nonconfirmé,aucun numéroenvoiwebhookAPIclic
  1. Le lecteur coche la case de consentement et envoie votre formulaire, qui envoie à Ikiform.
  2. Ikiform stocke l'inscription et envoie un webhook signé à votre relais.
  3. Le relais vérifie la signature et ajoute le lecteur à l'outil d'e-mailing comme non confirmé.
  4. L'outil d'e-mailing envoie au lecteur un lien de confirmation.
  5. S'il clique, l'outil le marque comme confirmé et lui envoie chaque numéro.
  6. S'il ne clique jamais, il reste non confirmé et ne reçoit pas la newsletter.
Tout ce qui suit le relais se passe dans l'outil d'e-mailing, y compris le texte de l'e-mail de confirmation, la page qu'ouvre le lien et les relances.

Le réglage de chaque outil

Chaque outil a sa propre notion de « non confirmé », et sa propre façon d'y placer un nouvel abonné ajouté par l'API. Si vous vous trompez, les abonnés sont ajoutés comme déjà confirmés, sans aucun e-mail :

OutilComment une inscription par API reçoit un e-mail de confirmationLe piège
KitCréez l'abonné avec state: "inactive", puis ajoutez-le à un formulaire dont l'incentive email est activé. La documentation des formulaires en masse de Kit indique que cela envoie l'incentive email ; testez l'endpoint unitaire avec une adresse à vousLa création d'abonné utilise state: "active" par défaut, et cet endpoint ne permet pas de changer l'état ensuite
MailerLiteActivez Double opt-in for API and integrations dans les réglages d'inscription. Envoyez aussi status: "unconfirmed", dont MailerLite a besoin avant d'écrire à un abonné existantEnvoyer unconfirmed pour une adresse déjà active lui redemande de confirmer
beehiivEnvoyez double_opt_override: "on" à la création de l'abonnement, ou "not_set" pour utiliser le réglage de la publication"off" rend l'abonné actif immédiatement, sans e-mail

Testez chacun avec une adresse à vous avant de vous y fier. Les réglages des outils changent, et l'e-mail lui-même se configure dans l'outil : son objet, son texte et la page qu'ouvre le lien.

Un relais qui ne confirme qu'une fois

Un relais basique demande une confirmation à chaque webhook reçu. Deux cas rendent cela problématique : un lecteur qui envoie trois fois en une minute reçoit trois e-mails, et un bot qui inscrit l'adresse d'une victime fait arriver votre confirmation dans sa boîte à chaque tentative. Ce Cloudflare Worker demande à l'outil au plus une confirmation par adresse et par jour :

src/index.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { addUnconfirmed } from "./tool";

export interface Env {
  IKIFORM_WEBHOOK_SECRET: string;
  TOOL_API_KEY: string;
  SEEN: KVNamespace;
}

const DAY = 86_400;

async function digest(text: string) {
  const bytes = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
  return [...new Uint8Array(bytes)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
}

export default {
  async fetch(request: Request, env: Env) {
    if (request.method !== "POST") return new Response(null, { status: 405 });
    const payload = await request.text();
    let event;
    try {
      event = await verifyWebhook({ payload, headers: request.headers, secret: env.IKIFORM_WEBHOOK_SECRET });
    } catch (error) {
      if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
      throw error;
    }
    if (event.type !== "submission.created" || event.data.fields.consent !== true) {
      return new Response(null, { status: 204 });
    }

    const email = String(event.data.fields.email).trim().toLowerCase();
    const key = `confirm:${await digest(email)}`;
    if (await env.SEEN.get(key)) return new Response("Confirmation already requested today", { status: 200 });

    const answer = await addUnconfirmed(env, email, event.data.fields.first_name);
    if (answer.status === 429) {
      return new Response("Rate limited", { status: 503, headers: { "retry-after": answer.headers.get("retry-after") ?? "60" } });
    }
    if (!answer.ok) return new Response(`Email tool answered ${answer.status}`, { status: 502 });

    await env.SEEN.put(key, event.id, { expirationTtl: DAY });
    return new Response(null, { status: 204 });
  },
};
wrangler.jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "newsletter-relay",
  "main": "src/index.ts",
  "compatibility_date": "2026-10-01",
  "routes": [{ "pattern": "hooks.example.com", "custom_domain": true }],
  "kv_namespaces": [{ "binding": "SEEN", "id": "<your KV namespace id>" }]
}
  • addUnconfirmed dans ./tool est l'appel de l'outil du tableau ci-dessus. Copiez son contenu depuis la page Kit, MailerLite ou beehiiv.
  • La clé KV est un SHA-256 de l'adresse en minuscules : le stockage ne contient donc jamais l'adresse elle-même. Elle expire au bout d'un jour.
  • La clé n'est écrite qu'une fois la requête acceptée par l'outil. Si l'outil échoue, Ikiform réessaie et la nouvelle tentative n'est pas bloquée.
  • Répondre 200 à une répétition indique à Ikiform que la livraison a réussi, elle n'est donc pas réessayée, et le corps explique pourquoi dans le journal de livraison.
  • Le Worker tourne sur un domaine personnalisé. Ikiform refuse les noms d'hôte workers.dev comme URL de webhook. La documentation des webhooks liste chaque règle d'URL et la signification de chaque réponse, et votre propre serveur montre un relais qui stocke chaque livraison une seule fois.
KV est cohérent à terme entre les emplacements : deux livraisons pour la même adresse à quelques secondes d'écart peuvent donc passer toutes les deux. C'est acceptable pour un e-mail de confirmation. S'il vous faut une garantie stricte, gardez la clé dans un Durable Object ou dans une base de données avec une colonne unique.

Ce que doit dire le formulaire

Un lecteur qui voit « Merci de votre inscription » puis ne trouve rien dans son dossier de newsletters pense que ça a échoué. Dites-lui ce qui se passe ensuite, sur la page où il arrive :

  1. Réglez la ligne de succès, ou votre page de remerciement, pour dire qu'il y a un e-mail à ouvrir : « Presque fini. Ouvrez l'e-mail que nous vous avons envoyé et confirmez votre adresse. »
  2. Nommez l'expéditeur à chercher, et suggérez le dossier spam si rien n'arrive au bout de quelques minutes.
  3. Dans l'outil d'e-mailing, faites ouvrir au lien de confirmation votre propre page « Vous êtes abonné », pour que le parcours se termine sur votre site.

La case de consentement du formulaire et l'e-mail de confirmation n'ont pas le même rôle. La case enregistre que quelqu'un a dit oui sur votre page. Le clic prouve que l'adresse appartient à la personne qui a dit oui. La plupart des listes veulent les deux. Le modèle de formulaire de newsletter contient la case obligatoire.

Pièges

  • Les abonnés existants. Quelqu'un de déjà confirmé s'inscrit à nouveau depuis une autre page. Ne le repassez pas en non confirmé ; la page MailerLite montre un relais qui cherche d'abord l'adresse.
  • Les personnes désinscrites. Une inscription n'autorise pas toujours à annuler une désinscription. beehiiv ne réactive que si vous envoyez reactivate_existing: true, et MailerLite ne réabonne qu'avec resubscribe: true. N'envoyez ces options que si le formulaire le dit.
  • Les scanners de liens. Certains filtres de messagerie d'entreprise ouvrent les liens des e-mails entrants pour les vérifier. Si un outil confirme au simple chargement d'une page, un scanner peut confirmer une adresse sur laquelle personne n'a cliqué. Vérifiez si la page de confirmation de votre outil demande d'appuyer sur un bouton.
  • La délivrabilité. La confirmation est le premier e-mail qu'un lecteur reçoit de vous. Envoyez-la depuis un domaine authentifié dans votre outil, sinon elle tombe en spam et l'inscription n'aboutit jamais.
  • Les non-confirmés s'accumulent. Ce ne sont pas encore des abonnés. Décidez dans votre outil s'il faut envoyer une relance, puis laissez-les tranquilles.

Vérifiez que tout fonctionne

  1. Envoyez le formulaire avec une adresse à vous. La page vous invite à vérifier votre boîte.
  2. Ouvrez la livraison sous Webhooks dans Ikiform. Elle affiche succeeded avec le 204 du relais.
  3. Ouvrez l'abonné dans votre outil d'e-mailing. Il est non confirmé, inactif ou en attente, selon l'outil.
  4. Ouvrez l'e-mail de confirmation et cliquez. L'abonné devient actif ou confirmé.
  5. Envoyez à nouveau la même adresse dans la journée. La livraison affiche 200 avec "Confirmation already requested today", et aucun second e-mail n'arrive.
  6. Inscrivez une adresse déjà confirmée. Elle reste confirmée et ne reçoit pas de nouvel e-mail de confirmation.

Questions

Une étape vous bloque, ou vous voulez un guide pour votre cas ? Écrivez à hello@ikiform.com.