Vous dépensez en Google Ads, campagnes socials, emailings… mais quand arrive l’heure de mesurer la performance : plus de trace des UTM sur votre simulateur ou votre widget adresse.
Résultat ? Attribution marketing cassée, ROI fantôme, et réunions d’analyse qui tournent en rond.
Chez kelvin, on aime quand les choses sont propres et traçables. Alors on a préparé un guide pour que vos UTM restent accrochés jusqu’au clic final — et même au-delà.
Comprendre les UTM
Un UTM (Urchin Tracking Module) est un petit paramètre que l’on accroche à une URL (ex. ?utm_source=google&utm_medium=cpc&utm_campaign=hiver
).
Son but : savoir d’où vient votre visiteur et à quelle campagne attribuer la conversion.
Sans lui ? Impossible d’aligner vos chiffres marketing avec la réalité commerciale.
Le scénario catastrophe que tout le monde connaît
« On veut suivre les UTM et les pousser dans HubSpot.
Mais après un clic pub et l’arrivée sur le simulateur/widget, ils disparaissent.
Du coup, impossible de les remonter via Zapier/Make. »
Effets secondaires :
- Données de tracking incomplètes.
- Attribution marketing qui s’écroule.
- Décisions média prises… au doigt mouillé.
Causes fréquentes :
- Widget embarqué qui recharge une page interne sans propager les paramètres.
- Redirection ou script JavaScript qui nettoie l’URL.
- Outil tiers qui ne transmet pas nativement les paramètres.
La méthode : CAPTER → CONSERVER → TRANSMETTRE
- CAPTER : récupérer les UTM dès la page d’arrivée.
- CONSERVER : stocker en sessionStorage (ou localStorage) pour survivre aux changements d’URL.
- TRANSMETTRE : les envoyer partout où c’est utile :
- Dans la src du simulateur (iframe ou page dédiée)
- Sur tous les boutons/CTA
- Dans les formulaires (inputs cachés)
- Vers HubSpot ou votre CRM via Zapier/Make/API
- Dans la src du simulateur (iframe ou page dédiée)
Tuto intégration : widget adresse + bouton
Ce script capture vos UTM, les garde en mémoire et les injecte dans vos liens, formulaires et iframe du simulateur.
Lien du code : https://jsfiddle.net/kelvintechnologies/6nfh5pxw/
HTML
<p>
Pour adapter le code Javascript à votre utilisation
<ul>
<li>
Modifiez l'adresse du simulateur. Variable <code>simulatorUrl</code>
</li>
<li>
Si besoin, adaptez la fonction <code>getUtmParameters</code> pour modifier les paramètres de tracking à transférer
</li>
</ul>
</p>
<div style="position: relative">
<input type="text" id="js-klv-address" class="c-form-input-field w-input" placeholder="Saisir une adresse">
<div id="js-klv-results" class="c-address-results">
</div>
</div>
Javascript
init_address_completion = (function(addressSelector, resultSelector) {
// Change simulatorUrl to your simulator URL
const simulatorUrl = 'https://app.go-kelvin.com/simulator/kelvin/new';
const addressInput = document.getElementById(addressSelector);
const resultsDiv = document.getElementById(resultSelector);
// Function to get URL parameters
const getUtmParameters = () => {
const urlParams = new URLSearchParams(window.location.search);
const utmParams = {
utm_campaign: urlParams.get('utm_campaign'),
utm_source: urlParams.get('utm_source'),
utm_content: urlParams.get('utm_content')
};
console.log(utmParams);
return utmParams;
};
var fetchAddressesFromText = function(text) {
fetch(`https://api-adresse.data.gouv.fr/search/?q=${encodeURIComponent(text)}`)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
displayData(data.features);
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
};
var clearAndHideResults = function(element) {
element.innerHTML = '';
element.style.visibility = 'hidden';
}
var displayData = function(features) {
clearAndHideResults(resultsDiv);
features.forEach(feature => {
const properties = feature.properties;
const coordinates = feature.geometry.coordinates;
const address = {
full: properties.label,
latitude: coordinates[1],
longitude: coordinates[0]
};
resultsDiv.innerHTML += row(address);
});
if (features.length > 0) {
resultsDiv.style.visibility = 'visible';
}
};
var row = function(address) {
let url = `${simulatorUrl}?lat=${address.latitude}&lng=${address.longitude}&display_address=${encodeURIComponent(address.full)}`;
// Add UTM parameters if they exist
const utmParams = getUtmParameters();
for (const [key, value] of Object.entries(utmParams)) {
if (value) {
url += `&${key}=${encodeURIComponent(value)}`;
}
}
return `<div><a href="${url}" target="_blank">${address.full}</a></div>`;
};
// Add event listener to input
addressInput.addEventListener('input', function() {
if (this.value.length > 2) { // Only search if more than 2 characters are entered
fetchAddressesFromText(this.value);
} else {
clearAndHideResults(resultsDiv);
}
});
});
init_address_completion('js-klv-address', 'js-klv-results');
CSS
.c-address-results {
position: absolute;
z-index: 20;
border: 1.5px solid #fff3;
background-color: #ffff;
box-shadow: 0 4px 20px #00000008;
border-radius: .75rem;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: .625rem;
padding: .625rem .875rem;
margin-top: 10px;
visibility: hidden;
}
.c-address-results a {
color: var(--primary--black);
font-family: Roboto,sans-serif;
font-size: 1rem;
line-height: 100%;
text-decoration: none;
}
Checklist avant mise en ligne
- ✅ Test sur un parcours complet depuis une annonce réelle
- ✅ Vérifier que tous les CTAs et iframe portent bien les UTM
- ✅ Contrôler que les formulaires envoient les paramètres dans votre CRM
Bonnes pratiques pour ne plus jamais perdre un UTM
- Standardiser une classe de bouton (.js-kelvin-cta) sur laquelle le script agit
- Utiliser sessionStorage plutôt que localStorage pour éviter la pollution longue durée
- Documenter la convention d’UTM en interne