Créa-blog

#100JoursPourCoder
Projet Créa-code

Ressources pour développeur web

Jour 20 : Connecter formulaire de newsletter HTML à Mailchimp

Temps de lecture : 15 minutes
Accueil Projets Jour 20 : Connecter formulaire de newsletter HTML à Mailchimp

Dans ce vingtième jour du défi #100JoursPourCoder, nous allons apprendre à relier un formulaire de newsletter en HTML à Mailchimp sans recharger la page – en Ajax. Nous utilisons l’architecture MVC de note site web Créa-code, donc tout sera structuré proprement : côté contrôleur, côté vue et côté JavaScript.

Mailchimp est un outil en ligne qui nous permet de créer des listes de contacts, d’envoyer des newsletters, et de gérer des campagnes email. Il est très utilisé par les sites web professionnels car il évite de tout gérer manuellement.

Notre objectif aujourd’hui est d’envoyer l’adresse email saisie dans le formulaire HTML directement vers Mailchimp, en utilisant leur API. Nous voulons que cette inscription soit fluide pour l’utilisateur, donc elle devra se faire sans rechargement de page, grâce à une requête Ajax. En retour, nous afficherons un message pour dire si l’inscription a réussi, si l’adresse est déjà connue ou si une erreur est survenue.

1. Comprendre la structure générale du projet

Avant de plonger dans le code, rappelons rapidement comment fonctionne notre projet.

Nous avons un système MVC personnalisé. Cela signifie que notre application est organisée en trois parties : les Modèles (pour la base de données notamment), les Vues (pour l’affichage HTML), et les Contrôleurs (pour la logique et les échanges entre modèle et vue).

Nous avons aussi un système de routes personnalisées. C’est ce système qui permet de dire quelle URL doit déclencher quelle méthode d’un contrôleur.

Pour notre projet, nous n’allons pas utiliser de base de données car nous voulons simplement envoyer l’email à Mailchimp qui le stockera. Mais nous allons tout de même passer par un contrôleur pour respecter notre logique MVC.

2. Le point de départ : notre formulaire HTML

Sur notre pied de page, nous avons déjà ce petit formulaire HTML :

<form action="#" method="post" id="newsletter-form">
    <input type="email" id="newsletter-email" name="email" placeholder="Votre adresse email" required>
    <button type="submit" class="btn-signin">S'inscrire</button>
    <p id="newsletter-message"></p>
</form>

Ce formulaire contient un champ pour saisir l’email et un bouton pour envoyer. Nous avons juste ajouté un paragraphe vide dans lequel nous afficherons un message de retour : succès ou erreur.

Pour l’instant, ce formulaire ne fait rien de particulier. Il est statique. Nous allons le rendre dynamique.

3. Ajouter une route vers notre contrôleur

Nous devons maintenant créer un chemin qui recevra les emails envoyés par notre formulaire. Pour cela, nous allons dans le fichier app/Route/routes.php. Ce fichier contient toutes les routes de notre site.

Nous allons ajouter la ligne suivante :

$router->post('/newsletter/subscribe', 'NewsletterController@subscribe');

Cette ligne veut dire que lorsqu’une requête POST est envoyée à l’URL /newsletter/subscribe, c’est la méthode subscribe() du contrôleur NewsletterController qui sera appelée.

4. Créer le contrôleur NewsletterController

Allons maintenant dans le dossier app/Controller, là où nous plaçons tous nos contrôleurs. Nous allons créer un nouveau fichier que nous appelerons NewsletterController.php.

Voici le contenu de base que nous allons mettre dedans :

<?php
namespace App\Controller;

use App\Core\Controller;

class NewsletterController extends Controller
{
    public function subscribe()
    {
        // Nous allons traiter ici l’inscription
    }
}

Ce fichier définit une classe qui hérite de notre contrôleur principal. Pour l’instant, la méthode subscribe() est vide. Nous allons y revenir un peu plus loin de ce chapitre.

5. Préparer le script JavaScript (Ajax)

Le but est que notre formulaire envoie l’email à Mailchimp sans recharger la page. Pour cela, nous utilisons JavaScript, et plus précisément une requête fetch() qui permet d’envoyer des données au serveur sans quitter la page.

Nous allons créer un fichier JavaScript dans public/assets/js/ que nous pouvons appeler newsletter.js.

Voici le contenu que nous allons mettre dedans :

document.addEventListener('DOMContentLoaded', function () {
    const form = document.getElementById('newsletter-form');
    const message = document.getElementById('newsletter-message');

    form.addEventListener('submit', function (e) {
        e.preventDefault(); // On empêche le rechargement de la page

        const email = document.getElementById('newsletter-email').value;

        fetch('/newsletter/subscribe', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ email: email })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                message.textContent = data.message;
                message.style.color = 'green';
                form.reset(); // On efface le champ après succès
            } else {
                message.textContent = data.message;
                message.style.color = 'red';
            }
        })
        .catch(error => {
            message.textContent = "Une erreur s'est produite.";
            message.style.color = 'red';
        });
    });
});

Ce code écoute l’événement de soumission du formulaire. Il empêche le comportement par défaut (le rechargement), puis envoie une requête POST à l’URL /newsletter/subscribe avec l’email. Quand la réponse revient, on affiche un message.

On inclus ce fichier JS dans votre vue footer, juste avant la balise </body> :

<script src="<?= BASE_URL ?>assets/js/newsletter.js"></script>

6. Ajouter la logique côté PHP – Mailchimp API

Revenons maintenant dans le contrôleur NewsletterController. Nous allons maintenant écrire la logique de communication avec l’API de Mailchimp. Commençons par lire les données envoyées en JSON :

$data = json_decode(file_get_contents('php://input'), true);

Cela nous permet d’obtenir les données envoyées par fetch() dans un tableau associatif. Nous allons maintenant vérifier que nous avons bien un email, et qu’il est valide :

if (!isset($data['email']) || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
    echo json_encode(['success' => false, 'message' => "Adresse email invalide."]);
    return;
}

Si tout va bien, on continue en préparant l’appel vers l’API de Mailchimp.

Il nous faut trois choses : notre clé API, le list ID de notre audience, et le serveur (comme us21us5, etc.). Imaginons que nous avons les identifiants suivants :

$apiKey = 'votre-cle-api-mailchimp';
$listId = 'votre-list-id';
$serverPrefix = 'us21';

Récupérer la clé API ($apiKey)

  1. Connecte-toi à ton compte Mailchimp : https://mailchimp.com/
  2. En haut à droite, clique sur ton avatar ou ton nom de compte, puis choisis « Account & billing ».
  3. Va dans l’onglet « Extras » puis clique sur « API keys ».
  4. Si tu n’as pas encore de clé, clique sur « Create A Key ».
  5. Une clé s’affiche dans la colonne « API key » — copie-la et colle-la dans ta variable PHP :
$apiKey = 'ta-cle-api-ici';

Trouver le List ID ($listId) de ton audience

  1. Dans Mailchimp, clique sur le menu « Audience ».
  2. En haut à gauche, clique sur « All contacts » si ce n’est pas déjà visible.
  3. Ensuite, clique sur « Settings » dans le menu secondaire.
  4. Choisis « Audience name and defaults ».
  5. Tout en bas de la page, tu verras une section appelée « Audience ID » — c’est ça le listId.

Colle-le ensuite dans ton script PHP :

$listId = 'xxxxxxxxxx';

Trouver le préfixe serveur ($serverPrefix)

Ta clé API contient en réalité l’indication du serveur dans sa partie finale.
Exemple :
Si ta clé est :

0123456789abcdef-us21

Alors ton serverPrefix est :

$serverPrefix = 'us21';

Tu peux aussi le repérer dans les URLs de l’interface Mailchimp, qui contiennent souvent us21us5us11, etc., en fonction du data center utilisé.

Nous construisons ensuite l’URL pour ajouter un nouvel abonné :

$url = "https://$serverPrefix.api.mailchimp.com/3.0/lists/$listId/members/";

Nous préparons les données à envoyer :

$postData = [
    'email_address' => $data['email'],
    'status' => 'subscribed'
];

Enfin, nous envoyons la requête avec CURL :

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $apiKey);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // à éviter en prod si possible

$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$response = json_decode($result, true);

Nous allons maintenant interpréter la réponse et renvoyer un message à JavaScript.

if ($httpCode === 200) {
    echo json_encode(['success' => true, 'message' => "Merci ! Vous êtes maintenant inscrit à la newsletter."]);
} elseif ($httpCode === 400 && isset($response['title']) && $response['title'] === 'Member Exists') {
    echo json_encode(['success' => false, 'message' => "Cette adresse est déjà inscrite."]);
} else {
    echo json_encode(['success' => false, 'message' => "Une erreur est survenue."]);
}

Et voilà ! Notre système fonctionne.

7. Améliorer les messages d’affichage pour l’utilisateur

Notre formulaire affiche déjà un message de retour dans un paragraphe HTML grâce au JavaScript. Ce message est mis à jour dynamiquement dès que Mailchimp nous répond.

Formation web et informatique - Alban Guillier - Formateur

Des formations informatique pour tous !

Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…

Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.

Découvrez mes formations Qui suis-je ?

Nous avons écrit dans le fichier newsletter.js ce passage :

if (data.success) {
    message.textContent = data.message;
    message.style.color = 'green';
    form.reset();
} else {
    message.textContent = data.message;
    message.style.color = 'red';
}

Ce code permet d’afficher le message de retour avec une couleur adaptée. Pour aller plus loin, nous pourrions ajouter des classes CSS spécifiques, comme success-message et error-message, mais pour l’instant, gardons les choses simples.

Nous avons aussi prévu un paragraphe vide dans le HTML :

<p id="newsletter-message"></p>

Il est important que ce paragraphe ait un identifiant (id) pour que notre script JavaScript puisse le modifier facilement. C’est lui qui sera mis à jour en fonction du résultat de l’inscription.

L’affichage immédiat d’un retour visuel est important à la fois pour l’expérience utilisateur et pour le référencement, car un formulaire fluide augmente les conversions et réduit les abandons.

En JavaScript, pour utiliser une variable CSS, on doit la récupérer avec getComputedStyle(document.documentElement) et utiliser .getPropertyValue('--nom-de-la-variable').

Voici comment faire dans notre script :

const rootStyles = getComputedStyle(document.documentElement);
const successColor = rootStyles.getPropertyValue('--success-color').trim();
const errorColor = rootStyles.getPropertyValue('--error-color').trim();

// Puis dans ta logique
if (data.success) {
    message.textContent = data.message;
    message.style.color = successColor;
    form.reset();
} else {
    message.textContent = data.message;
    message.style.color = errorColor;
}

8. Accessibilité : pensons à tous les utilisateurs

Même si le formulaire fonctionne déjà, il est bon d’ajouter quelques améliorations pour les personnes utilisant un lecteur d’écran.

Nous pouvons par exemple donner un rôle au message :

<p id="newsletter-message" role="alert" aria-live="assertive"></p>

Le rôle alert indique qu’un lecteur d’écran doit lire le message à voix haute dès qu’il est mis à jour. Le champ aria-live assure que le contenu est bien détecté comme dynamique. Ce sont de petites choses qui ne changent rien pour un visiteur standard, mais qui améliorent l’accessibilité pour d’autres.

9. Que faire si l’email est déjà inscrit ?

Lorsque nous envoyons une adresse email à Mailchimp, leur API vérifie si cette adresse existe déjà dans notre audience.

Si l’adresse est déjà connue, Mailchimp renvoie une erreur spécifique que nous avons captée avec ce test :

if ($httpCode === 400 && isset($response['title']) && $response['title'] === 'Member Exists') {
    echo json_encode(['success' => false, 'message' => "Cette adresse est déjà inscrite."]);
}

C’est une bonne pratique de prévenir l’utilisateur quand il tente une inscription déjà existante. Cela évite des frustrations. L’important ici est d’afficher un message clair, et non une erreur technique. Notre message est volontairement simple et rassurant.

10. Protéger notre endpoint : sécurisation légère

Même si cette fonctionnalité n’est pas critique (elle ne modifie pas notre base de données), nous pouvons ajouter une forme de sécurité légère.

Nous pouvons :

  • limiter la fréquence des soumissions (anti-spam),
  • filtrer certains domaines (par exemple les adresses temporaires),
  • ajouter une clé secrète ou un captcha,
  • vérifier l’origine de la requête.

Par exemple, pour limiter le spam, nous pourrions enregistrer dans un fichier temporaire l’adresse IP et la dernière soumission, puis refuser si moins de 10 secondes se sont écoulées. C’est une protection simple mais efficace.

Une autre solution consiste à utiliser un champ caché qui ne doit pas être rempli (honeypot), ou un token CSRF généré côté PHP et validé à la réception. Ces mesures seront utiles surtout si un jour notre formulaire devient une cible de robots.

Mais pour aujourd’hui, restons concentrés sur la fonctionnalité de base.

11. Optimisation SEO : pourquoi c’est utile même en Ajax

Certains pourraient penser qu’un formulaire qui fonctionne en JavaScript n’est pas utile pour le SEO. C’est faux. Même si le contenu des réponses n’est pas indexé, la présence d’un formulaire visible, bien structuré et sémantique contribue au référencement.

Voici quelques bonnes pratiques à retenir pour optimiser notre formulaire newsletter :

  • Le formulaire doit être visible dès le chargement, pas masqué derrière un clic.
  • Il est préférable de le placer dans une balise section ou aside, et de lui donner un titre avec une balise h2 ou h3.
  • Il faut éviter de cacher les champs ou de charger le formulaire en AJAX après coup.

Exemple d’intégration SEO-friendly dans un pied de page :

<footer>
  <section aria-labelledby="newsletter-title">
    <h2 id="newsletter-title">Recevez nos conseils pour apprendre le code</h2>
    <form id="newsletter-form">
      <input type="email" name="email" id="newsletter-email" placeholder="Votre adresse email" required>
      <button type="submit">S'inscrire</button>
      <p id="newsletter-message" role="alert" aria-live="assertive"></p>
    </form>
  </section>
</footer>

Ce balisage est propre, sémantique, et montre à Google que cette section est importante.


Nous avons relié un formulaire HTML à l’API de Mailchimp, dans un projet structuré en MVC. L’adresse email de l’utilisateur est envoyée à une route dédiée de notre système. Cette route appelle un contrôleur. Ce contrôleur prépare la requête vers Mailchimp. Une réponse est reçue, puis renvoyée au navigateur en JSON.

Notre JavaScript intercepte le formulaire, empêche le rechargement, envoie les données, et affiche un message de retour dans la page. Le tout est fluide, sans page blanche, et très moderne.

Nous avons aussi vu comment afficher ces messages de manière accessible, et comment prévoir le cas où l’email existe déjà.

Enfin, nous avons compris que même un formulaire dynamique peut avoir un rôle dans le SEO, à condition d’être bien structuré.

Ce tutoriel est une excellente base pour créer d’autres formulaires dynamiques sur notre site. Par exemple, un formulaire de contact, un formulaire de participation à un challenge, ou même une mini FAQ interactive.

Voici quelques idées pour améliorer notre système dans les prochains jours :

  • Créer une classe MailchimpHelper pour centraliser la logique d’appel API.
  • Ajouter une option de double opt-in dans Mailchimp pour vérifier l’inscription.
  • Logger les tentatives d’inscription (email, date, succès ou non) pour avoir des statistiques.
  • Créer une section spéciale dans notre dashboard admin pour voir combien d’inscriptions ont été réalisées chaque semaine.

Et pourquoi pas un jour, afficher dans le profil utilisateur s’il est inscrit à la newsletter ou non ? Ou même permettre de se désinscrire avec un bouton.

Intégrer un formulaire de newsletter avec Mailchimp peut sembler compliqué au premier abord, mais une fois bien compris, cela devient un exercice très formateur. Nous avons utilisé PHP, JavaScript, et notre structure MVC pour créer un formulaire moderne, fluide, et connecté à un outil professionnel.

Ce tutoriel nous a permis de travailler sur de nombreux concepts : les requêtes Ajax, la gestion des routes, les API externes, la sécurité de base, et l’accessibilité.

C’est une belle étape dans la construction de notre site code.crea-troyes.fr, qui progresse jour après jour pour offrir aux visiteurs une expérience professionnelle et engageante.

La suite demain avec la mise en place du dark mode …

Live on Twitch