Le cas le plus simple : deux balises, aucun outillage. Il vaut aussi pour un site généré (Hugo, Jekyll, Eleventy) et pour n'importe quel CMS où l'on peut éditer un gabarit.
Prérequis : la clé publique et le domaine déclaré (voir le README, étapes 1 et 2).
Dans le gabarit commun du site, juste avant </body> :
</body>
<script src="https://messagerie.inovertix.com/inocampagne.js" data-marque="INOCMP_PUB_votre_cle_publique" data-endpoint="https://messagerie.inovertix.com/api/inocampagne/public" defer></script>
defer n'est pas décoratif : sans lui, le script bloque le rendu de la page. Avec lui, il s'exécute après l'analyse du document, et le formulaire apparaît sans que le visiteur ait attendu.
defer
Là où le formulaire doit apparaître — pied de page, colonne latérale, milieu d'un article :
<div data-inocampagne-form></div>
Vous pouvez en mettre plusieurs sur la même page : chacun est rendu indépendamment. C'est utile pour un article long (un formulaire au milieu, un en bas).
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Sora Parfume — Nouveautés</title> </head> <body> <main> <h1>Nos nouveautés</h1> <p>…</p> <!-- Le formulaire d'inscription, au milieu de l'article --> <section aria-label="Inscription à la newsletter"> <div data-inocampagne-form></div> </section> <p>…</p> </main> <footer> <!-- Et un second, en pied de page --> <div data-inocampagne-form></div> </footer> <script src="https://messagerie.inovertix.com/inocampagne.js" data-marque="INOCMP_PUB_votre_cle_publique" data-endpoint="https://messagerie.inovertix.com/api/inocampagne/public" defer></script> </body> </html>
Le formulaire vit dans un shadow DOM : votre CSS ne l'atteint pas, et le sien ne fuit pas chez vous. C'est délibéré — un formulaire déformé par une règle input { … } du thème est un formulaire qu'on n'ose plus poser chez un client.
input { … }
Ce qui est réglable se règle dans CONTROL, pas dans votre CSS : couleur principale et logo viennent de la fiche de la marque, les libellés et la mention de consentement viennent de l'endpoint /config.
/config
Le conteneur, lui, est à vous : marges, largeur, fond, position. Le formulaire fait au plus 420 px de large et s'adapte à ce que vous lui donnez.
/* Votre CSS : vous habillez le CONTENEUR, pas le formulaire. */ [data-inocampagne-form] { max-width: 26rem; margin: 2.5rem auto; }
Un visiteur sans JavaScript ne verra pas le formulaire. Si c'est une contrainte, pointez simplement vers la page hébergée par CONTROL :
<noscript> <p> <a href="https://plateforme.inovertix.com/news/sora-parfume/inscription"> Inscrivez-vous à notre newsletter </a> </p> </noscript>
C'est la même page que celle que vous partagez sur les réseaux sociaux : brandée, sans indexation, et elle applique exactement les mêmes règles de consentement.
Si vous préférez votre propre formulaire (pour l'intégrer à un design existant), appelez l'API directement. Deux précautions, et le reste suit :
<form id="newsletter"> <label for="nl-email">Adresse email</label> <input id="nl-email" type="email" name="email" required autocomplete="email"> <!-- 1. HONEYPOT : hors écran, hors tabulation, hors lecteurs d'écran. --> <input type="text" name="inocampagne_website" tabindex="-1" aria-hidden="true" autocomplete="off" style="position:absolute;left:-9999px;width:1px;height:1px"> <button type="submit">Je m'inscris</button> <p><small> En vous inscrivant, vous acceptez de recevoir nos emails. Désinscription en un clic dans chaque message. </small></small></p> </form> <script> (function () { var form = document.getElementById('newsletter'); // 2. PIÈGE TEMPOREL : l'horodatage d'affichage du formulaire. var renderedAt = Date.now(); form.addEventListener('submit', function (e) { e.preventDefault(); fetch('https://messagerie.inovertix.com/api/inocampagne/public/subscribe' + '?k=INOCMP_PUB_votre_cle_publique', { method: 'POST', // `text/plain` : la requête reste « simple », donc aucun préflight OPTIONS. headers: { 'Content-Type': 'text/plain;charset=UTF-8' }, body: JSON.stringify({ email: form.email.value, source_url: location.href, rendered_at: renderedAt, inocampagne_website: form.inocampagne_website.value, }), }) .then(function (r) { return r.json(); }) .then(function (body) { form.innerHTML = '<p>' + (body.message || 'Merci !') + '</p>'; }) // Échec silencieux : le visiteur n'a pas à voir notre panne. .catch(function () { /* rien */ }); }); })(); </script>
La mention de consentement n'est pas optionnelle. C'est elle qui rend l'opt-in défendable le jour où quelqu'un demande « pourquoi je reçois ça ? ». Si vous la réécrivez, gardez les deux informations : ce qu'il va recevoir, et comment en sortir.
À faire une fois, avant de livrer :
Une inscription passe : votre adresse apparaît dans CONTROL → INOCAMPAGNE → Profils, avec la provenance « Formulaire /news » ;
Le consentement est le bon : opt_in pour la marque attendue (ou inconnu en double opt-in, jusqu'au clic de confirmation) ;
opt_in
inconnu
Le mauvais domaine échoue : appelez /ping depuis un autre domaine, vous devez recevoir 403 origin_not_allowed. Si ça passe, la liste des domaines est trop large.
/ping
403 origin_not_allowed
<div data-inocampagne-form>
www.
202
Le reste du dépannage vit dans le README.