Perché parti della tua pagina vengono tagliate nella heatmap di Matomo (e come risolvere)

Gli screenshot delle heatmap di Matomo tagliano silenziosamente tutto quello che sta dentro container con scroll e wrapper con overflow:hidden. Sidebar, modali e layout 'scrollytelling' spariscono oltre il loro bordo visibile, e i click atterrano su quello che era a schermo al momento della cattura. Ecco perché succede e come gestiamo la cosa.

Se hai aperto una heatmap di Matomo e hai trovato la sidebar troncata, la metà inferiore di un modale che manca, o marcatori di click che fluttuano sopra contenuto che non sembra appartenere a loro, i click in sé vanno bene. Matomo li ha registrati alle coordinate giuste. Quello che non funziona è lo screenshot sottostante. Qualche wrapper sulla pagina ha overflow: hidden, overflow: auto, o overflow: scroll impostato, e il renderer di Matomo tratta tutto quello che va oltre il bordo visibile di quel wrapper come se non esistesse. Così la heatmap ti mostra una fetta della pagina invece della pagina che i tuoi visitatori hanno visto davvero.

La soluzione più rapida è un'estensione gratuita per Chrome che manteniamo noi, si chiama Matomo Heatmap Helper. Neutralizza i container con overflow subito prima di ogni cattura, lascia che il renderer veda il documento completo, e ripristina gli stili originali dopo. Il resto di questo post spiega come fare la stessa cosa senza estensione, più qualche fix permanente che vale la pena mettere in produzione.

Come risolvere senza l'estensione

C'è uno snippet da console che risolve il problema subito prima di ogni cattura, e qualche fix permanente da mettere in produzione. Scegli quello che si adatta ai vincoli con cui stai lavorando.

Elenca tutti gli elementi con overflow limitato sulla pagina

Prima di cambiare qualcosa, scopri quali wrapper stanno tagliando. Apri la pagina in Chrome, premi F12 per aprire i DevTools, passa alla Console e incolla:

js
// Elenca tutti gli elementi che stanno tagliando contenuto
Array.from(document.querySelectorAll('*')).filter(el => {
  const s = getComputedStyle(el);
  return ['hidden','auto','scroll'].includes(s.overflow)
      || ['hidden','auto','scroll'].includes(s.overflowY);
});

Ottieni la lista esatta dei nodi che il renderer di Matomo tratterà come box a dimensione fissa. I soliti sospettati sono sidebar, modali, wrapper di scroll personalizzati attorno a <main>, e vecchi wrapper clearfix con overflow: hidden per motivi di layout che non sono più rilevanti da anni.

Il fix rapido: rimuovi le restrizioni overflow dalla console

Questo è lo snippet che incolliamo nella console del browser subito prima di triggerare la cattura della heatmap di Matomo. Scorre ogni elemento che sta tagliando e porta overflow e overflow-y a visible. Nel momento in cui Matomo serializza il DOM, nulla si nasconde oltre un bordo visibile.

js
// Incolla nella console del browser subito prima della cattura.
// Porta ogni container overflow della pagina a 'visible'.
document.querySelectorAll('*').forEach(el => {
  const s = getComputedStyle(el);
  if (['hidden','auto','scroll'].includes(s.overflow) ||
      ['hidden','auto','scroll'].includes(s.overflowY)) {
    el.style.overflow = 'visible';
    el.style.overflowY = 'visible';
  }
});

La pagina sembrerà strana per un momento. Le sidebar si espandono alla loro altezza completa, i modali si allungano oltre il bordo del viewport, e qualsiasi cosa dipendesse da un container a altezza fissa improvvisamente non ce l'ha più. Va bene così. Stai catturando la heatmap, non navigando il sito. Ricarica quando hai finito.

È la strada rapida. Funziona per catture una tantum e per i cicli di revisione in cui hai bisogno di uno screenshot pulito adesso e non vuoi aspettare una modifica al codice. Per qualcosa che ricapturerai regolarmente, metti in produzione uno dei fix permanenti qui sotto.

Fix CSS permanente con scope alla modalità di cattura

La risposta più pulita quando controlli il foglio di stile è un override solo per la heatmap che disattiva ogni container overflow nel momento in cui il tracker di Matomo viene caricato. Un blocco CSS, una riga JS, e sei a posto.

css
/* Modifica i selettori per corrispondere ai wrapper del tuo sito */
html.heatmap-mode .sidebar,
html.heatmap-mode main,
html.heatmap-mode .modal-shell {
  overflow: visible !important;
  overflow-y: visible !important;
  height: auto !important;
  max-height: none !important;
}
js
// Aggiungi al tuo sito. Attiva la classe ogni volta che il tracker di Matomo è sulla pagina.
if (window._paq) document.documentElement.classList.add('heatmap-mode');

Ora l'override si attiva solo sulle pagine dove Matomo si sta caricando comunque, il che va bene per una revisione della heatmap ed è invisibile al resto del tuo traffico. Se preferisci uno scope più stretto, condizionalo a un query param (?heatmap=1) o a un foglio di stile separato incluso solo nella copia staging su cui punti Matomo.

Elimina il container con scroll annidato

Se la tua pagina ha overflow: auto su <main> o su qualche altro wrapper per ragioni di "scrollytelling", il fix architetturale è eliminarlo e lasciare che il documento scorri. Il renderer di Matomo sa riprodurre lo scroll del documento, non sa riprodurre una posizione di scroll interna di un container annidato. In più ottieni una UX migliore su mobile (iOS Safari ha le sue opinioni sui container con scroll annidati) e l'accessibilità migliora perché lo scroll da tastiera e la navigazione con screen reader iniziano a funzionare come gli utenti si aspettano.

È una modifica più grande dell'override CSS, ma è quella che impedisce al problema di ripresentarsi la prossima volta che qualcuno aggiunge una nuova sezione al layout.

Sostituisci overflow: hidden clearfix con display: flow-root

I vecchi wrapper clearfix con overflow: hidden erano una soluzione per contenere figli float. display: flow-root fa la stessa cosa senza tagliare nulla, ed è sicuro da usare in tutti i browser che vale la pena supportare dal 2018.

css
/* Modifica il selettore per corrispondere al tuo wrapper clearfix */
.row-with-floats {
  display: flow-root;
}

Stesso comportamento di contenimento, nessun taglio, e smetti di combattere con lo screenshot. Il modo rapido per trovare i candidati è cercare nel tuo CSS overflow: hidden e verificare se ognuno sia effettivamente pensato per tagliare qualcosa. Di solito no.

Una nota sul trade-off

Qualunque fix permanente scegli, limita lo scope dell'override (una classe, un query param, un foglio di stile solo per la heatmap) invece di cambiare gli stili live per tutti. I tuoi visitatori stanno vedendo il layout che hai progettato per loro, e il modale che dovrebbe scorrere dentro il suo box deve continuare a farlo per loro. L'override deve esistere solo per il renderer che Matomo punta sulla pagina.

Perché Matomo non riesce a renderizzare i tuoi container overflow

La cattura degli screenshot di Matomo è un processo in due fasi. Prima il tracker serializza il tuo DOM live in HTML e lo spedisce. Poi il tuo server Matomo ri-renderizza quell'HTML a un viewport fisso per produrre lo screenshot che vedi nella vista heatmap. Nessuna sessione browser, nessuna posizione di scroll portata dal visitatore, nessun aggiustamento di layout guidato da JS. Solo un file HTML renderizzato a freddo da un IP diverso.

Il renderer sa riprodurre lo scroll del documento, ed è per questo che le pagine lunghe vengono catturate bene. Quello che non sa riprodurre è la posizione di scroll interna di un container overflow: auto annidato, perché quella vive nel browser del visitatore e non finisce mai nel DOM serializzato. Quando il renderer incontra un wrapper overflow: hidden, fa quello che fa qualsiasi browser e taglia. Il risultato è uno screenshot che sembra la fetta visibile della pagina in un momento specifico, con tutto il resto sparito.

Le coordinate dei click peggiorano la cosa. Matomo registra i click relativi al documento, non relativi alla posizione di scroll interna di qualsiasi container stesse scorrendo l'utente. Un click sul terzo elemento di una sidebar scorrevole viene memorizzato alla coordinata y che occupava al momento del click. Quando il renderer fotografa la sidebar a scroll-top zero, quella coordinata y appartiene ora al primo elemento. Il marcatore si posiziona lì. Il click sembra atterrato sul link sbagliato.

Cosa sta fallendo davvero

Alcuni pattern che continuiamo a incontrare:

  • Sidebar e modali con le proprie scrollbar. Il wrapper ha un'altezza fissa e overflow: auto, la lista interna è più alta, e solo la parte visibile al momento della cattura finisce nello screenshot.
  • Pagine "scrollytelling" con overflow: auto su <main> o un wrapper simile. Il body non scorre, l'elemento interno sì, e la heatmap cattura un viewport di contenuto.
  • Vecchi wrapper clearfix con overflow: hidden che non sono effettivamente pensati per tagliare nulla. Erano pensati per contenere float. Tagliano ancora, e fanno ancora sparire contenuto dallo screenshot.
  • Menu a tendina o accordion personalizzati che animano tagliando il contenuto con overflow: hidden più una transizione di altezza. Lo stato chiuso è quello che vede Matomo.
  • mask CSS o clip-path su un container. Proprietà diversa, stesso effetto sullo screenshot. Il fix è lo stesso: disattivarlo in modalità di cattura.

Se la tua heatmap manca di contenuto o i marcatori di click non si allineano agli elementi che ti aspetteresti, stai incontrando almeno uno di questi. Spesso più d'uno sulla stessa pagina.

Questa è anche la stessa famiglia di problemi che rompe font, immagini e header sticky nello stesso screenshot. Abbiamo scritto un post più lungo sugli screenshot rotti delle heatmap di Matomo che copre il resto, e post separati su perché i font non si caricano e perché le immagini non si caricano dato che emergono quasi altrettanto spesso.

Cosa faremmo noi

Se controlli il foglio di stile, metti in produzione l'override solo per la heatmap. Un blocco CSS con scope a una classe che attivi quando il tracker di Matomo è caricato. È il diff più piccolo che risolve il problema in modo permanente e non tocca quello che vedono i visitatori.

Se il layout ha un container con scroll annidato che ti dava fastidio anche per altri motivi, prendi il fix architetturale e lascia scorrere il documento. Ti risparmierai questo problema per ogni futura cattura di heatmap, e i tuoi utenti mobile te ne saranno grati.

Se nessuna delle due è raggiungibile (nessun accesso al foglio di stile, widget di terze parti che non puoi ridisegnare, un CMS che non ti permette di distribuire CSS personalizzato), l'estensione Chrome Matomo Heatmap Helper è quella che usiamo sui siti dei clienti dove non possiamo cambiare lo stack. Scorre gli stessi container overflow che trova lo snippet, li neutralizza per la cattura e li ripristina dopo, così la pagina è intatta per il visitatore successivo. Gratuita, open source, codice su GitHub.

Martez è il progetto più grande da cui è nata l'estensione. Connette Matomo con Meta Ads e Google Ads così ROAS, CLV e attribuzione stanno accanto alla tua web analytics invece che in un foglio di calcolo separato. È in beta privata. Unisciti alla lista d'attesa se ti è rilevante.

La maggior parte delle volte è una modifica al foglio di stile di distanza. Vale la pena farlo una volta.

Perché parti della tua pagina vengono tagliate nella heatmap di Matomo (e come risolvere) - Martez Blog