Cookie first-party GA4 : récupérer les sessions Not Set
Procédure pour reconstruire l'attribution perdue en server-side : cookie first-party, variables GTM et dimensions personnalisées GA4.
Sur un setup GA4 server-side ou via Measurement Protocol, il n’est pas rare de voir 30 à 50 % des conversions classées en (not set). La cause : les hits arrivent au serveur sans le contexte navigateur (pas d’UTM, pas de referrer, pas de client_id natif), et toute l’attribution s’évapore. Sur un compte e-commerce que j’ai audité, le ratio mesuré était de 48 % de conversions Not Set — 410 achats sur 862 sans source identifiée.
La technique pour récupérer cette donnée existe et tient en quatre briques : un cookie d’attribution first-party, des variables GTM, des dimensions personnalisées GA4, et une séquence de validation. Voici la procédure complète, applicable telle quelle.
- Le problème vient du Measurement Protocol qui ignore le contexte navigateur.
- La solution : capturer les UTM côté client dans un cookie first-party, puis les renvoyer en dimensions custom sur chaque hit.
- Implémentation : 1 variable JS GTM + 1 cookie + 5 dimensions personnalisées GA4 + 1 modif du tag GA4.
- Le temps total est de 2 à 3 heures, validation comprise.
Pourquoi le server-side perd l’attribution
En setup client-side classique, GA4 reçoit le hit directement depuis le navigateur de l’utilisateur. Il a accès au document.referrer, à l’URL avec ses paramètres UTM, aux cookies first-party historiques. L’attribution est calculée à partir de ces signaux.
En server-side ou Measurement Protocol, le hit transite par votre serveur GTM. Si la couche client ne fait pas son travail de transmission des données contextuelles, GA4 reçoit un événement décontextualisé. Pour les sessions où l’UTM n’a pas été propagé correctement, ou pour les conversions différées (plusieurs jours après la première visite), la source d’origine est perdue.
Cas concret observé sur un compte audité :
- 862 achats totaux sur 30 jours
- 452 achats avec source identifiée (52 %)
- 410 achats en
(not set)(48 %) - Les 443 achats trackés côté client-side correspondent presque exactement aux 452 attribués correctement — ce qui confirme que les 410 Not Set sont des hits server-side qui ont perdu le contexte
Sans correction, c’est 48 % du chiffre d’affaires qui circule sans attribution. Reporting marketing inutilisable, ROAS faussé, décisions budgétaires aveugles.
La logique de correction
L’idée est de capturer les UTM au moment où ils sont encore disponibles (côté client, dès l’arrivée du visiteur), de les stocker dans un cookie first-party qui survit aux sessions ultérieures, puis de les renvoyer comme dimensions custom sur chaque hit GA4 (y compris les hits server-side).
GA4 ne pourra toujours pas reconstituer ces données dans ses dimensions natives (source, medium, campaign), mais les dimensions custom les exposeront proprement dans les rapports et BigQuery.
Étape 1 — Créer le cookie d’attribution dans GTM
Une variable JavaScript personnalisée gère la capture et la restitution.
Variable JS - Cookie Attribution
Type : JavaScript personnalisé
function() {
var COOKIE_NAME = '_te'; // nom du cookie
var COOKIE_DURATION_DAYS = 30; // durée de vie
function getAttributionCookie() {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var c = cookies[i].trim();
if (c.indexOf(COOKIE_NAME + '=') === 0) {
try {
return JSON.parse(decodeURIComponent(c.substring(COOKIE_NAME.length + 1)));
} catch (e) { return null; }
}
}
return null;
}
function setAttributionCookie(data) {
var d = new Date();
d.setDate(d.getDate() + COOKIE_DURATION_DAYS);
document.cookie = COOKIE_NAME + '=' +
encodeURIComponent(JSON.stringify(data)) +
';expires=' + d.toUTCString() + ';path=/;SameSite=Lax';
}
function getUTMParameters() {
var p = new URLSearchParams(window.location.search);
var utm = {
utm_source: p.get('utm_source') || '',
utm_medium: p.get('utm_medium') || '',
utm_campaign: p.get('utm_campaign') || '',
utm_content: p.get('utm_content') || '',
utm_term: p.get('utm_term') || '',
timestamp: Date.now()
};
// Fallback : si pas d'UTM, lire le referrer
if (!utm.utm_source && document.referrer) {
try {
var ref = new URL(document.referrer);
utm.utm_source = ref.hostname.replace('www.', '');
utm.utm_medium = 'referral';
} catch (e) {}
}
return utm;
}
var existing = getAttributionCookie();
var current = getUTMParameters();
// Logique de priorité : on n'écrase QUE si un nouvel UTM est présent
if (current.utm_source && (!existing || current.utm_source !== existing.utm_source)) {
setAttributionCookie(current);
return current;
}
return existing || current;
}
Trois logiques clés à comprendre :
- Persistance 30 jours — l’utilisateur peut revenir 3 semaines plus tard, l’attribution est préservée
- Fallback referrer — si l’utilisateur arrive sans UTM mais depuis un site externe, on capture le referrer comme source
- Priorité au nouveau touchpoint — un nouveau click identifié écrase le précédent (logique “last paid click” implicite)
Étape 2 — Exposer chaque UTM comme variable GTM séparée
Le cookie renvoie un objet JSON. Il faut une variable GTM par dimension à renvoyer à GA4. Cinq variables, type JavaScript personnalisé, qui s’appuient sur la variable maître.
Exemple pour utm_source :
function() {
var attr = {{JS - Cookie Attribution}};
return attr && attr.utm_source ? attr.utm_source : '(not set)';
}
Répéter pour utm_medium, utm_campaign, utm_content, utm_term. Nommer proprement : JS - UTM Source, JS - UTM Medium, etc.
Étape 3 — Déclarer les dimensions personnalisées dans GA4
Direction Admin → Définitions personnalisées → Dimensions personnalisées → Créer.
| Nom de la dimension | Scope | Paramètre d’événement |
|---|---|---|
| Custom UTM Source | Event | custom_utm_source |
| Custom UTM Medium | Event | custom_utm_medium |
| Custom UTM Campaign | Event | custom_utm_campaign |
| Custom UTM Content | Event | custom_utm_content |
| Custom UTM Term | Event | custom_utm_term |
Attention aux limites GA4 : 50 dimensions event-scoped maximum par propriété. Si vous êtes déjà proche du plafond, planifier l’usage.
Étape 4 — Modifier le tag GA4 pour envoyer les paramètres
Sur votre tag GA4 Event Configuration (le tag de config), ajouter dans la section “Event parameters” :
| Parameter name | Value |
|---|---|
custom_utm_source | {{JS - UTM Source}} |
custom_utm_medium | {{JS - UTM Medium}} |
custom_utm_campaign | {{JS - UTM Campaign}} |
custom_utm_content | {{JS - UTM Content}} |
custom_utm_term | {{JS - UTM Term}} |
Si vous avez un container server-side, renvoyer ces mêmes paramètres dans le client GA4 du serveur GTM. Sans ça, les hits server-side perdront à nouveau l’information.
Étape 5 — Valider en DebugView + monitoring
Test immédiat
- Activer le mode preview GTM et le DebugView GA4
- Visiter le site avec
?utm_source=test&utm_medium=cpc&utm_campaign=validation - Vérifier dans DebugView que les 5 paramètres
custom_utm_*sont présents sur chaque event - Fermer le navigateur, rouvrir 10 minutes plus tard sans UTM : vérifier que le cookie
_teest toujours présent et que les paramètres custom continuent de remonter
Monitoring 7 à 14 jours
- Créer un rapport personnalisé avec la dimension
Custom UTM Sourceet la métriqueConversions - Comparer la part de
(not set)sur la dimension nativeSession sourcevs la dimensionCustom UTM Source - Sur les comptes que j’ai migrés, la dimension custom remonte généralement 75 à 90 % des cas qui étaient en Not Set natif
Précision importante
La dimension native (not set) ne disparaît pas. Le cookie d’attribution alimente une dimension parallèle plus complète. Le reporting “vrai” passe désormais par cette nouvelle dimension. C’est exactement la logique de la Cause 4 détaillée dans l’article résoudre le (not set) dans GA4.
Cas particuliers à anticiper
Sites cross-domain
Si l’utilisateur transite entre marque.fr et shop.marque.fr, le cookie _te doit être défini sur le domaine racine. Adapter la ligne du cookie :
document.cookie = COOKIE_NAME + '=' + ... + ';path=/;domain=.marque.fr;SameSite=Lax';
Conformité RGPD
Le cookie _te est un cookie d’attribution. En toute rigueur, il doit être soumis au consentement marketing/analytique selon votre interprétation. Vérifier que votre Consent Mode v2 ne bloque pas l’écriture du cookie quand le consentement est accordé.
Server-side strict
Si vous voulez envoyer aussi ces UTM côté Meta CAPI ou Microsoft Ads, ajouter les mêmes paramètres dans les tags correspondants. La logique reste : capture côté client, persistence cookie, restitution sur tous les hits.
Mise en perspective
Cette procédure couvre la Cause 4 du Not Set en GA4 (attribution perdue en server-side). Pour les autres causes — high cardinality, désalignement de scope, Enhanced Measurement mal configuré — voir l’article général résoudre le (not set) dans GA4. Si la suite logique est de corriger les classifications natives de GA4 (Paid Search en Organic, etc.), passer aux canaux personnalisés GA4. Et pour le choix du modèle d’attribution qui exploitera ces données propres, voir les 6 modèles d’attribution.
Sur les setups e-commerce complexes, cette procédure est l’une des composantes d’un audit tracking complet. La méthodologie globale est détaillée dans la petite-fille méthodologie d’audit.
En synthèse
48 % de conversions Not Set n’est pas une fatalité du server-side. Avec un cookie first-party, 5 variables GTM et 5 dimensions custom, on récupère la quasi-totalité de l’attribution perdue. Le coût d’implémentation est de quelques heures ; le gain en qualité de pilotage marketing dure des années.
Sources
- Google Analytics Help — Custom dimensions — limites et bonnes pratiques GA4
- Simo Ahava — Server-side tracking and the cost of broken attribution — référence sur la perte de contexte en server-side