Cross-domain tracking GTM: configurazione e debug pratico

·5 min lettura
Cross-domain tracking GTM: configurazione e debug pratico

In un audit su un cliente B2B, ho visto 42% delle sessioni convertite attribuite a "(direct)". Quattro casi su dieci. Il sito principale era su marca.it, il configuratore prodotto su app.marca.it, il pagamento gestito da un terzo dominio (pay.gateway.eu). Nessun linker cross-domain configurato. Il risultato: ogni sessione si spaccava in tre, Google Ads sottostimava le conversioni e i report di attribution erano scollegati dalla realtà.

Il cross-domain tracking è una di quelle configurazioni che funzionano in test ma si rompono in produzione perché qualcuno ha aggiunto un terzo dominio "solo per il checkout". Vediamo come farlo girare per davvero.

Quando serve davvero

Cross-domain tracking serve quando l'utente attraversa più di un dominio nella stessa sessione e tu vuoi che GA4 lo veda come un unico viaggio. Casi tipici:

  • Sito vetrina su dominio.it, ecommerce su shop.dominio.it (sottodominio: di solito non serve, GA4 lo gestisce nativamente)
  • Sito principale su dominio.it, checkout su pay.shopify.com o secure.gateway.com (dominio diverso: serve linker)
  • Marketplace con vendor multipli ognuno su un dominio proprio
  • Multi-paese con .it, .fr, .de che vuoi misurare come un unico flusso

Non serve quando:

  • Tutti i sottodomini sono sullo stesso dominio root e GA4 è già configurato per il root (yoursite.it, non www.yoursite.it)
  • Apri un dominio terzo solo come pop-up che torna alla pagina di partenza senza creare sessione
  • Il dominio terzo carica dentro un iframe che riceve il contesto via postMessage

Come funziona il linker

Quando configuri il linker, GA4 (via gtag.js o GTM) aggiunge a tutti i link verso i domini configurati un parametro _gl nell'URL. Esempio:

https://pay.gateway.eu/checkout?_gl=1*1k2mhne*_ga*MTQ1Mjc4OTc5MS4xNzM4...

Il parametro _gl contiene una versione codificata del client ID GA4. Sul dominio di destinazione, se anche lì GA4 è installato, lo script lo legge e riusa lo stesso client ID per la sessione successiva. Risultato: GA4 vede una sola sessione, attribuita correttamente alla sorgente originale.

Setup in GTM (client-side)

Su entrambi i domini, GTM deve esistere e il tag GA4 Configuration deve avere il linker abilitato.

Sul dominio sorgente (es. dominio.it)

  1. Apri il tag GA4 Configuration
  2. Sezione "Configurazione tag" → "Domini cross-domain"
  3. Aggiungi i domini di destinazione (es. pay.gateway.eu, shop.altrosito.it)
  4. Non aggiungere il dominio corrente (è già implicito)
  5. Salva e pubblica

In alternativa via Google Tag (gtag.js):

gtag('config', 'G-XXXXXXX', {
  'linker': {
    'domains': ['pay.gateway.eu', 'shop.altrosito.it']
  }
});

Sul dominio destinazione (es. pay.gateway.eu)

Stessa configurazione: il tag GA4 Configuration deve avere il linker con i domini sorgente nella lista. La configurazione è bidirezionale: senza la lista anche sul dominio terzo, il _gl arriva ma non viene letto.

Se non hai accesso al GTM del dominio terzo (es. è un gateway di pagamento esterno), il cross-domain non funzionerà. In quel caso la strategia cambia: si tracking lato server con client_id passato come parametro custom via webhook di ritorno del gateway.

I 5 errori che vedo più spesso

1. Il dominio terzo non ha GA4 installato

Il problema più frequente nei checkout su gateway esterni. Tu sul tuo sito hai il linker, l'utente clicca "Paga", arriva su pay.gateway.eu/checkout?_gl=1*... ma su quella pagina non c'è GA4. Risultato: il client ID viaggia ma muore lì.

Soluzione: o convinci il gateway a installare GA4 (raro), o sposti il tracking lato server passando client_id via webhook al backend, oppure usi un dominio di checkout proprietario tramite Stripe Connect / Checkout custom.

2. Linker abilitato solo su un lato

Configurato su dominio.it ma dimenticato su shop.dominio.it. Sintomo: il parametro _gl arriva in URL ma il dominio destinazione genera comunque un nuovo client_id.

Diagnosi: apri DevTools → Application → Cookies → cerca _ga su entrambi i domini. Se hanno valori diversi dopo il salto, il linker non legge.

3. Filtri Google Ads "Auto-tagging" che mangiano il parametro

Su alcune configurazioni Google Ads, il parametro gclid viene stripped a livello CDN o WAF. Lo stesso può capitare con _gl se hai regole troppo aggressive. Verifica nei log del WAF o nelle URL rewrite rules.

4. Server-side redirect che perdono il query string

Se sul dominio destinazione la prima cosa che succede è un redirect 301 verso una versione canonica (es. da pay.gateway.eu/checkout a pay.gateway.eu/checkout/), e il redirect è scritto male, il _gl si perde.

Diagnosi: apri DevTools → Network → osserva la chain di redirect. Se vedi che da una request all'altra il _gl scompare, il redirect è il colpevole.

5. Single Page Application senza History API events

Su SPA (React, Vue, Next.js client-side), il primo pageview dopo il salto cross-domain spesso non triggera. Risultato: il client ID viene importato ma GA4 non manda eventi finché l'utente non clicca da qualche parte.

Soluzione: forzare un page_view manuale dopo il route change iniziale, oppure usare il History Change trigger di GTM con configurazione "Once per Page" disabilitata.

Debug operativo

Tre tool che uso sempre, in ordine:

Tag Assistant Companion (Chrome)

L'estensione ufficiale Google mostra tutti i tag che sparano, il client_id corrente e i parametri inviati. Se vedi che dopo il salto cross-domain il client_id cambia, c'è un problema. Se rimane invariato, il linker funziona.

Realtime di GA4

Apri Realtime su una scheda, naviga il flusso cross-domain in un'altra. Devi vedere una sola sessione attiva, non due. Se ne vedi due (una per dominio), il linker non sta funzionando.

BigQuery export

Per audit retrospettivi, query sulla tabella events_* filtrando per user_pseudo_id e ordinando per event_timestamp. Se per un utente vedi user_pseudo_id diversi a pochi secondi di distanza con pagine su domini diversi, hai sessioni spezzate.

SELECT
  user_pseudo_id,
  event_timestamp,
  event_name,
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location') AS page
FROM `progetto.analytics_XXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260501' AND '20260507'
  AND event_name IN ('page_view', 'purchase')
ORDER BY user_pseudo_id, event_timestamp
LIMIT 1000;

Cerca pattern in cui un acquisto su pay.gateway.eu ha un user_pseudo_id diverso dalla view item su dominio.it per lo stesso utente identificato dal CRM. Se ne trovi, il problema esiste.

Quando passare al server-side

Se hai più di tre domini coinvolti, gateway che non puoi modificare e flussi che includono backend-to-backend, il cross-domain client-side non basta. Si passa a un'architettura server-side dove il client_id viene passato come parametro custom in tutte le chiamate webhook, e il backend ricostruisce la sessione lato GTM Server.

Questo è un cambio di stack importante. Vale la pena se il revenue di campagne digitali supera il 30% del fatturato totale: sotto, il rapporto effort/uplift non torna.

Limiti

Il cross-domain non recupera sessioni interrotte: se l'utente chiude il browser tra un dominio e l'altro e torna 4 ore dopo, sono due sessioni. Il linker funziona solo entro i 30 minuti standard di sessione GA4 (configurabili ma il default è 30 min).

Inoltre, anche con il setup perfetto, alcune browser policy nel 2026 (in particolare Brave e Firefox Strict Privacy) bloccano il _gl perché lo classificano come "tracking parameter". Sul totale del traffico è di solito un 3-5% di utenti, ma se il tuo target è privacy-conscious il numero sale.

Prossimi passi

Se sospetti un problema cross-domain ma non sai dove, parti con un audit tracking GA4 che include il check dei linker e l'analisi delle sessioni "(direct)" sospette. Se il setup è da fare da zero, lo affrontiamo dentro il flusso di consulenza GA4 o, per ecommerce, dentro tracking ecommerce.

Per chi vuole approfondire il debug via BigQuery, ho già scritto sul tema in User journey analytics con GA4 e BigQuery SQL: la query di check sessioni spezzate è una specializzazione di quel pattern.

Correlati