Un formulaire de contact rempli sans qu’on sache d’où vient réellement le visiteur, c’est un lead à moitié exploitable pour une équipe commerciale. Ce constat, l’agence marketing d’un client B2B l’avait fait après plusieurs mois de campagnes payantes : le formulaire HubSpot embarqué sur le site vitrine WordPress recevait bien des soumissions, mais impossible de savoir si elles venaient de la campagne LinkedIn, de la newsletter ou d’une recherche organique.
Le CRM HubSpot capturait pourtant très bien la source de trafic — à condition que le formulaire reçoive l’information. Il ne s’agissait pas de reconstruire toute la chaîne de tracking, seulement de faire circuler ce que l’URL de la page contenait déjà : les paramètres UTM posés par les campagnes.
Lire les paramètres UTM côté page
Les paramètres utm_source, utm_medium, utm_campaign et utm_content arrivent dans la chaîne de requête de l’URL au moment où le visiteur clique sur un lien de campagne. Ils sont lus côté client, sans dépendance à un plugin d’analytics tiers :
function wpmLireParametresUtm() {
const params = new URLSearchParams(window.location.search);
const cles = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content'];
const valeurs = {};
cles.forEach(function (cle) {
if (params.has(cle)) {
valeurs[cle] = params.get(cle);
}
});
return valeurs;
}
Un point important : ces paramètres ne survivent pas à une navigation entre plusieurs pages du site sans effort supplémentaire. Si le visiteur arrive sur la page d’accueil puis navigue vers la page de contact avant de remplir le formulaire, l’URL de cette dernière page ne contient plus les paramètres d’origine. Il faut donc les stocker temporairement, par exemple dans le sessionStorage du navigateur, dès la première page vue.
Transmettre les valeurs au formulaire HubSpot
Le formulaire HubSpot embarqué expose un événement onFormReady via son script de chargement, qui permet d’agir sur les champs juste avant l’affichage :

window.addEventListener('message', function (event) {
if (event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormReady') {
const form = document.querySelector('form.hs-form');
const utm = JSON.parse(sessionStorage.getItem('wpm_utm') || '{}');
Object.keys(utm).forEach(function (cle) {
const champ = form.querySelector('input[name="' + cle + '"]');
if (champ) {
champ.value = utm[cle];
}
});
}
});
Ce fonctionnement suppose que les champs cachés correspondants (utm_source, utm_medium, etc.) existent déjà dans la configuration du formulaire côté HubSpot — une opération de quelques minutes dans l’éditeur de formulaire, sans code, mais indispensable pour que les valeurs transmises soient réellement enregistrées avec le lead.
Ce que cette solution ne fait pas
Cette intégration reste volontairement limitée à la transmission des paramètres UTM au moment de la soumission. Elle ne synchronise pas :
- L’historique complet des pages visitées avant conversion
- Les scores d’engagement calculés côté HubSpot
- Les mises à jour ultérieures du contact dans le CRM
Une synchronisation bidirectionnelle complète entre WordPress et HubSpot est un projet distinct, souvent porté par un middleware dédié plutôt que par quelques lignes de JavaScript sur le site vitrine.
Vérifier que les données arrivent bien
Avant de considérer l’intégration comme terminée, un test simple : soumettre le formulaire depuis une URL contenant des paramètres UTM factices, puis vérifier dans HubSpot que le contact créé porte bien ces valeurs dans les propriétés correspondantes. C’est un test qui prend deux minutes et qui évite bien des malentendus trois semaines plus tard, quand l’équipe marketing demande pourquoi la moitié des leads n’a « aucune source ».
En résumé
Faire circuler les paramètres UTM jusqu’à un formulaire HubSpot embarqué ne demande ni extension ni synchronisation CRM complète : une lecture d’URL, un stockage de session, et un remplissage de champs cachés au moment de l’affichage du formulaire suffisent à redonner un contexte exploitable à chaque lead généré.