In breve, la risposta rapida
8 min di letturaUna single-page application carica un solo documento HTML e cambia schermata con JavaScript, quindi un tag che scatta solo al caricamento della pagina registra una sola pageview per l'intera visita. Il tracking SPA risolve il problema con una pageview virtuale a ogni cambio di route, usando gli eventi della History API (l'impostazione di GA4 "Modifiche alla pagina basate sugli eventi della cronologia del browser" ascolta pushState, popState e replaceState) oppure chiamate manuali a page_view. Il doppio conteggio nasce quando attivi due di questi metodi insieme. Le pageview mancanti dipendono da router che non toccano l'URL o da pageview inviate prima che l'URL si aggiorni.
Che cos'è il tracking delle SPA?
In una single-page application, il tracking delle SPA consiste nel registrare una visualizzazione di pagina virtuale ogni volta che l'app cambia schermata con JavaScript. Il browser carica il documento HTML una sola volta e non esegue nessun nuovo caricamento di pagina per i cambi di route successivi. Google descrive le SPA come "siti web che caricano un documento HTML una sola volta e recuperano qualsiasi contenuto aggiuntivo tramite le API JavaScript", e fissa l'obiettivo in modo chiaro: "La chiave per misurare correttamente le visualizzazioni di pagina delle SPA è contare le visualizzazioni di pagina per ogni schermata con cui l'utente interagisce e rilevare correttamente il referrer, così da poter ricostruire in modo corretto il percorso dell'utente."
Una visualizzazione di pagina virtuale è un evento di pageview che il tuo strumento di analytics invia senza un vero caricamento di pagina. Il browser non richiede nessun nuovo documento, ma il report mostra una nuova pagina con il suo URL e il suo referrer, proprio come se l'avesse fatto.
Perché un tag analytics standard non rileva le pageview delle SPA?
Un tag analytics standard non rileva le pageview delle SPA perché invia la sua pageview quando lo script viene eseguito per la prima volta, e in una SPA lo script viene eseguito una sola volta per visita. Un visitatore che arriva su /, apre /pricing e poi /signup tramite link interni all'app ha preso decisioni su tre schermate, mentre un tag che scatta solo al caricamento registra una sola pageview, quella di /.
Il danno va oltre il conteggio delle pageview. Google osserva che senza pageview virtuali "Google Analytics tratta la SPA come una singola pagina, generando metriche distorte", e che "tutto il tempo di coinvolgimento viene attribuito al caricamento iniziale della pagina, rendendo impossibile analizzare il tempo trascorso sulle singole schermate". Anche clic e scroll vengono assegnati all'URL di atterraggio. La guida su pageview, sessioni e utenti spiega perché, in una SPA, un numero basso di pageview per sessione è prima di tutto un segnale di tracking e solo dopo un segnale di comportamento.
![]()
Come segnala un cambio di route la History API?
La History API segnala un cambio di route attraverso metodi che il tuo router richiama ed eventi che il browser genera, e i due non corrispondono uno a uno. Questa mancata corrispondenza è il motivo per cui i tracker devono restare in ascolto in più punti.
| Cambio | Cosa lo attiva | Evento del browser generato |
|---|---|---|
history.pushState() | Il tuo router, su un link interno all'app | Nessuno |
history.replaceState() | Il tuo router, quando riscrive l'URL corrente | Nessuno |
| Pulsante indietro o avanti | Il visitatore | popstate |
history.back(), forward(), go() | Il tuo codice | popstate |
Cambio di hash (#section) | Un link o un codice che modifica il frammento | hashchange |
MDN è esplicito sulle prime due righe: "chiamare semplicemente history.pushState() o history.replaceState() non attiva un evento popstate." Un tracker che ascolta solo popstate vede i clic su indietro e avanti, ma perde ogni navigazione in avanti fatta attraverso i tuoi link. I tracker risolvono il problema avvolgendo o osservando direttamente pushState e replaceState.
Come traccia GA4 le single-page application?
GA4 traccia le single-page application attraverso un'impostazione di misurazione avanzata che invia un page_view quando cambia la cronologia del browser. Il centro assistenza di Google descrive il trigger di page_view come "ogni volta che la pagina viene caricata o lo stato della cronologia del browser viene modificato dal sito attivo", e dice che l'impostazione avanzata "è in ascolto di pushState, popState e replaceState". Google consiglia questa strada "se la tua SPA usa la History API, in particolare i metodi pushState() e replaceState() per aggiornare le schermate."
Per attivarla:
- In Google Analytics, apri Amministrazione.
- In Raccolta e modifica dei dati, clicca su Flussi di dati, poi sul tuo flusso web.
- In Misurazione avanzata, attiva l'interruttore.
- Clicca sull'icona delle impostazioni e, in Visualizzazioni di pagina, clicca su Mostra impostazioni avanzate.
- Abilita sia Caricamenti di pagina sia Modifiche alla pagina in base agli eventi della cronologia del browser.
- Salva.
L'altra strada è manuale. Google indica gli "Eventi personalizzati" per i siti in cui le schermate vengono mostrate senza un cambio di URL, come un'app che usa oggetti DocumentFragment. In quel caso devi inviare tu stesso, dal router, gtag('event', 'page_view', { page_title: '...', page_location: '...' }).
Cosa causa il doppio conteggio nel tracking delle SPA?
Il doppio conteggio nel tracking delle SPA si verifica quando due meccanismi inviano ciascuno una pageview per lo stesso cambio di route. Ecco le configurazioni più comuni che lo provocano:
- Google Tag Manager più gli eventi della cronologia di GA4. L'avvertimento di Google: "Se configuri i tag con Google Tag Manager, non abilitare il tracking automatico della cronologia in Google Analytics, perché può portare al doppio conteggio delle visualizzazioni di pagina." Un trigger Cambio cronologia di GTM scatta già "quando il frammento dell'URL cambia o quando un sito usa l'API HTML5 pushstate."
- Chiamate manuali a page_view più l'impostazione della cronologia.
send_page_view: falsenon blocca le pageview basate sulla cronologia. Google lo afferma così: "Se la misurazione avanzata è abilitata, Google Analytics invierà eventipage_viewin base ai cambi della cronologia del browser anche se impostisend_page_view: false." Disattiva Modifiche alla pagina in base agli eventi della cronologia del browser quando il tuo router invia le proprie pageview. - replaceState usato per filtri o schede. GA4 elenca replaceState tra i cambi della cronologia che ascolta, quindi un elenco prodotti che scrive
?sort=pricenell'URL conreplaceStatepuò generare una pageview a ogni cambio di filtro. Verifica questo caso in DebugView prima di fidarti dei conteggi delle pagine nelle schermate piene di filtri. - Due tag Google con lo stesso ID. Uno snippet gtag inserito direttamente nel codice e un tag Google di GTM che puntano allo stesso ID di misurazione inviano ciascuno i propri eventi.
Cosa causa le pageview mancanti nel tracking delle SPA?
Le pageview mancanti nel tracking delle SPA nascono da cambi di route che non arrivano mai alla History API e da pageview inviate nel momento sbagliato.
- Router che non cambiano mai l'URL. Un'app che sostituisce i componenti in memoria non dà niente da ascoltare a un listener della cronologia. Usa la strada dell'evento personalizzato.
- Routing con hash e un tracker che guarda solo la cronologia. Cambiare
#/pricinggenerahashchange. Controlla se il tuo strumento conta i cambi di frammento e, se non lo fa, configuralo. - Pageview inviate prima che l'URL si aggiorni. Un
page_viewche scatta prima dipushStateregistra il vecchiopage_location. In DebugView, Google consiglia di confrontare ognipage_view"con l'eventopage_viewprecedente per verificare che il referrer e la posizione della pagina siano stati aggiornati correttamente." - Referrer obsoleti. L'esempio di evento personalizzato di Google salva il vecchio URL e lo passa come
page_referrer, perché ildocument.referrerdel browser resta fermo al referrer di atterraggio originale per tutta la visita.
Una trappola correlata si trova fuori dal router. web.dev osserva che la back/forward cache "non funziona per le 'soft navigation' all'interno di una single-page app", quindi un clic su indietro dentro la tua app è un evento della cronologia, mentre un clic su indietro che riporta alla tua app da un altro sito può ripristinare l'intera pagina dalla memoria e non generare nessun evento della cronologia.
![]()
Come verificare che il tracciamento SPA funzioni?
Per verificare il tracciamento SPA, naviga nell'app con la modalità debug attiva e controlla che ogni nuova schermata produca esattamente una visualizzazione di pagina, con la posizione e il referrer corretti. Il controllo indicato da Google è lo stesso: abilitare la modalità debug, "navigare nella tua single-page application" e confermare "un nuovo evento page_view in DebugView" per ogni schermata virtuale. Poi ripeti il test con i pulsanti indietro e avanti, con un cambio di filtro e con un link hash, perché sono i casi in cui le visualizzazioni si duplicano o si perdono. La checklist di verifica dell'analytics applica la stessa idea a qualsiasi strumento di tracciamento, mentre la guida alla durata media della sessione mostra cosa fa un tracciamento SPA rotto ai dati sul tempo di permanenza.
Dashboard in tempo reale
Monitoraggio degli obiettivi
Tracciamento senza cookie
Due correzioni minori aiutano a rendere i numeri affidabili. Azzera la posizione di scorrimento a ogni cambio di route con window.scrollTo(0, 0), così la profondità di scroll si riferisce alla nuova schermata e non a quella vecchia. Inoltre invia la visualizzazione di pagina solo dopo che il router ha aggiornato URL e titolo.
Come gestisce Flowsery la navigazione SPA?
Flowsery traccia la navigazione SPA in automatico, quindi un cambio di route in React Router o Next.js compare come visualizzazione di pagina a sé, senza codice aggiuntivo. La documentazione dell'SDK npm di Flowsery elenca "le visualizzazioni di pagina, inclusa la navigazione SPA" tra i tracciamenti automatici, e le FAQ sui prezzi dichiarano che Flowsery "conta una visualizzazione di pagina ogni volta che un visitatore carica una pagina del tuo sito, comprese le navigazioni delle single-page app." Per le app che usano i frammenti dell'URL per il routing, l'SDK npm ha l'opzione hashMode, e la documentazione dello script descrive una versione del tracker con routing hash per le SPA. Se la tua app cambia schermata senza cambiare l'URL, l'SDK espone trackPageview(), così puoi inviarne una dal tuo codice. La pagina analytics per React spiega come Flowsery misura le route lato client, gli eventi personalizzati, i funnel e le entrate nelle app React.
Domande frequenti
Che cos'è una visualizzazione di pagina virtuale?
Una visualizzazione di pagina virtuale è un evento di pageview inviato senza un vero caricamento di pagina, usato quando una SPA cambia schermata tramite JavaScript. Porta con sé una propria posizione di pagina e un proprio referrer, quindi i report trattano ogni schermata come una pagina separata. Senza di essa, una visita a una SPA appare come un'unica lunga visualizzazione della pagina di atterraggio.
GA4 traccia automaticamente i cambi di route nelle SPA?
Sì, se la misurazione avanzata è attiva e l'opzione Modifiche alla pagina basate sugli eventi della cronologia del browser è abilitata nelle impostazioni avanzate delle visualizzazioni di pagina. Questa impostazione intercetta pushState, popState e replaceState. Non aiuta con le app che cambiano schermata senza cambiare l'URL.
Perché GA4 conta due volte ogni visualizzazione di pagina della SPA?
Due meccanismi stanno inviando visualizzazioni di pagina per lo stesso cambiamento. Le coppie più comuni sono i trigger della cronologia di GTM insieme agli eventi della cronologia di GA4, oppure le chiamate manuali a page_view insieme agli eventi della cronologia di GA4. Disattivane uno. Google precisa che send_page_view: false non blocca le visualizzazioni di pagina basate sulla cronologia.
pushState fa scattare popstate?
No. MDN precisa che chiamare history.pushState() o history.replaceState() non fa scattare un evento popstate. Lo fanno scattare solo azioni del browser come i pulsanti indietro e avanti, o chiamate come history.back().
Come dovrebbe funzionare page_referrer in una SPA?
Ogni visualizzazione di pagina virtuale dovrebbe riportare come referrer l'URL della schermata precedente. Salva il vecchio URL prima del cambio di route e passalo come page_referrer insieme al nuovo page_location. Altrimenti ogni schermata riporta il referrer originale dell'atterraggio.
La back/forward cache influisce sul tracciamento delle SPA?
Non per le navigazioni all'interno dell'app. web.dev precisa che la bfcache non funziona per le soft navigation dentro una SPA. Si applica invece quando un visitatore esce dalla tua app e ci torna con il pulsante indietro: se la pagina è idonea, l'intera pagina può essere ripristinata dalla memoria senza un nuovo caricamento.
Come attivo il tracciamento SPA in GA4?
Apri Admin, clicca su Flussi di dati, scegli il tuo flusso web e attiva la Misurazione avanzata. Poi clicca sull'icona delle impostazioni, apri Mostra impostazioni avanzate sotto Visualizzazioni di pagina e abilita sia Caricamenti di pagina sia Modifiche alla pagina basate sugli eventi della cronologia del browser. Salva. Questo percorso funziona quando il tuo router usa pushState e replaceState.
Devo attivare il tracciamento della cronologia di GA4 se uso Google Tag Manager?
Lascialo disattivato. Google avverte che usare entrambi può portare a un doppio conteggio delle visualizzazioni di pagina. Un trigger Cambio cronologia di GTM scatta già quando cambia il frammento dell'URL o quando un sito usa l'API HTML5 pushstate.
Come traccio le route hash come #/pricing in una SPA?
Cambiare il frammento fa scattare hashchange, quindi un tracker che osserva solo la History API può non rilevarlo. Controlla se il tuo strumento conta i cambi di frammento e configuralo se non lo fa. L'SDK npm di Flowsery ha l'opzione hashMode, e la sua documentazione dello script descrive una versione del tracker con routing hash.
Come posso verificare che la mia SPA invii una visualizzazione di pagina per schermata?
Attiva la modalità debug, naviga nell'app e cerca un nuovo evento page_view in DebugView per ogni schermata. Confronta ciascuno con il page_view precedente per confermare che posizione della pagina e referrer si siano aggiornati. Poi ripeti con i pulsanti indietro e avanti, un cambio di filtro e un link hash.
Questo articolo ti è stato utile?
Facci sapere cosa ne pensi!
Vedici più spesso su Google
Con un clic imposti Flowsery come fonte preferita e i nostri articoli salgono in Notizie principali, Modalità AI e AI Overview.
Prima di andare...
Flowsery
Analytics per il tuo sito che parte dalle entrate
Monitora ogni visitatore, sorgente e conversione in tempo reale. Semplice, potente e senza cookie.
Dashboard in tempo reale
Monitoraggio degli obiettivi
Tracciamento senza cookie
Termini del glossario correlati


Perché il bounce rate di GA4 è solo l'engagement rate al contrario
Il bounce rate di GA4 è la quota di sessioni senza interazione. Come lo definisce Google, in cosa differisce da Universal Analytics e dove aggiungerlo.


Cosa conta il report Pagine di destinazione di GA4 e dove resta vuoto
Il report Pagine di destinazione di GA4 elenca la prima pagina di ogni sessione. Dove trovarlo, le metriche predefinite, perché compaiono righe (not set) e come aggiungere la fonte.


Come il tracciamento della ricerca interna di GA4 registra ciò che digitano i visitatori
Configura la ricerca interna di GA4 con la misurazione avanzata, aggiungi i tuoi parametri di query, trova la dimensione Termine di ricerca e traccia le ricerche senza URL.


Impostare le proprietà utente di GA4 e analizzarle nei report
Imposta le proprietà utente di GA4 con gtag o Tag Manager, registrale come dimensioni personalizzate a livello utente e resta entro il limite di 25 proprietà.


Come collegare Search Console a GA4 e pubblicarne i report
Scopri come collegare Search Console a GA4 da Amministrazione, quali ruoli ti servono, come pubblicare i due report nella Raccolta e quali dati non si possono unire.


Cosa fa la bfcache alle navigazioni indietro e ai tuoi conteggi di pageview
La bfcache, o back/forward cache, ripristina una pagina dalla memoria quando clicchi avanti o indietro. Quali pagine sono idonee e perché gli strumenti di analytics la perdono o la contano due volte.
Articoli correlati


Come creare metriche calcolate in GA4 con una quota di cinque slot
Google limita le metriche calcolate di GA4 a 5 per proprietà standard. La sintassi delle formule, le unità, dove compaiono e cosa una formula non può usare.


Configurare il raggruppamento dei contenuti in GA4 con un solo parametro
Configura i gruppi di contenuti in GA4 con il parametro content_group in gtag o Tag Manager, leggi la dimensione Gruppo di contenuti ed evita le righe (not set).


Come aggiungere le annotazioni di Google Analytics in GA4 e tenere un registro delle modifiche
In GA4, le annotazioni di Google Analytics fissano una nota con data sui grafici a linee. Chi può aggiungerle, i limiti di 60 e 150 caratteri, il tetto di 1.000 e l'uso come registro delle modifiche.