La cattura degli screenshot di Matomo funziona in due fasi, ed è proprio nel mezzo che le cose si rompono.
Quando qualcuno visita la tua pagina, il JavaScript di tracciamento serializza il DOM in una stringa HTML (usa una libreria che si chiama TreeMirror) e la spedisce al server Matomo. Poi il server prende quell'HTML e lo renderizza per generare l'immagine di sfondo che vedi nella vista heatmap.
Il punto è che la pagina viene ri-renderizzata in un contesto totalmente diverso. Il server Matomo non ha i tuoi cookie, non ha sessioni, ha un'origine diversa e non ha idea di cosa i framework JavaScript abbiano fatto alla pagina dopo il caricamento. Tutto quello che funzionava perché girava in un browser vero con le credenziali del tuo dominio può rompersi quando lo stesso HTML viene renderizzato a freddo su un altro server.
Se tieni a mente questo, la maggior parte dei bug degli screenshot inizia a tornare.
Come si presentano gli screenshot rotti
I problemi più frequenti:
- L'immagine hero si vede bene nel browser ma appare come icona rotta nella heatmap
- Una griglia prodotti scorrevole mostra solo la prima riga, il resto sparisce
- La navigazione sticky si piazza sopra il contenuto della pagina nello screenshot
- I font del brand vengono rimpiazzati da font di sistema generici
- Risorse con percorsi relativi tipo
/assets/banner.webpnon si caricano proprio - Le pagine SPA vengono catturate mentre stanno ancora renderizzando, con metà del contenuto che manca
Ognuno di questi ha una causa tecnica precisa. Vediamoli.
CORS che blocca immagini e font
Questo è il più comune. L'immagine hero, le foto prodotto o le immagini di sfondo escono come riquadri vuoti o icone rotte nello screenshot della heatmap.
Il motivo: le immagini nel browser si caricano senza problemi perché il browser ha i tuoi cookie e il contesto di sessione. Ma quando il server Matomo prova a scaricare https://cdn.yoursite.com/hero.jpg, il CDN vede un'origine che non conosce e rifiuta la richiesta. CORS, classico.
Lato server basta aggiungere Access-Control-Allow-Origin: * agli header di risposta del CDN. La documentazione di Matomo ne parla nella guida alla configurazione delle heatmap.
Se non hai il controllo del CDN o preferisci non toccare la configurazione del server, l'alternativa è incorporare le risorse direttamente nel DOM come data URI base64 prima che Matomo catturi la pagina. L'HTML serializzato si porta dietro tutte le immagini inline e il server non deve scaricare nulla. Vale per src, srcset, immagini di sfondo CSS, riferimenti SVG e poster dei video.
Container con scroll che tagliano il contenuto
Hai una sezione con altezza fissa e scrollbar. Nello screenshot della heatmap compare solo la parte visibile. Tutto quello che sta sotto la piega? Sparito.
Elementi con overflow: hidden o overflow: auto tagliano il contenuto alla loro altezza renderizzata. Matomo serializza il DOM nello stato visivo del momento, quindi l'HTML catturato riflette il clientHeight, non lo scrollHeight completo.
Per risolvere: niente altezze fisse sui container di contenuto. Usa min-height al posto di height e togli overflow: hidden dagli elementi che contengono contenuto scorrevole.
Header sticky e fissi che coprono la pagina
La navigazione sticky funziona bene nel browser, ma nello screenshot si pianta sopra al contenuto e copre tutto.
Elementi con position: fixed o position: sticky sono posizionati rispetto alla viewport. Sul server non c'è nessuna viewport, quindi collassano sul contenuto sottostante.
Matomo aggiunge una classe matomoHeatmap all'elemento <html> durante il rendering server-side dello screenshot. Puoi sfruttarla per scrivere regole CSS che valgono solo durante la cattura:
html.matomoHeatmap .your-sticky-header {
position: relative;
top: auto;
}L'header sticky diventa un elemento a flusso normale nello screenshot, senza cambiare nulla per gli utenti reali. La documentazione di Matomo ne parla nelle FAQ su come risolvere la sovrapposizione degli header nelle heatmap e sull'applicazione di fogli di stile personalizzati durante la cattura.
Se non vuoi mantenere regole CSS extra, l'approccio alternativo consiste nel rilevare gli elementi header e nav con posizionamento fixed o sticky, convertirli in position: relative, azzerare top/bottom/left/right e, per gli elementi fixed, inserire un div placeholder per non far spostare il layout. Dopo la cattura, tutto torna com'era.
URL relativi che smettono di funzionare
Alcune immagini e fogli di stile si caricano sul tuo sito ma mancano nello screenshot di Matomo, anche se non sono cross-origin. Sembra strano finché non ci pensi.
La pagina usa URL relativi tipo /images/banner.jpg. Nel browser, questo si risolve rispetto al tuo dominio. Nel contesto di rendering di Matomo, /images/banner.jpg si risolve rispetto al server Matomo. Il file lì non esiste.
Puoi usare URL assoluti dappertutto, oppure aggiungere un tag <base href="https://yoursite.com/"> nel <head>. Se nessuna delle due è praticabile, uno script pre-cattura può cercare nel documento tutti gli URL relativi in src, href, srcset e background-image CSS e riscriverli come assoluti usando l'origine corrente della pagina.
Font personalizzati che diventano font di sistema
I font del brand sono spariti. Lo screenshot mostra un qualsiasi font di sistema disponibile sul server, di solito qualcosa di orribile.
Le regole @font-face puntano a file di font ospitati su CDN o sul tuo server. Quando il server Matomo prova a caricarli, viene bloccato dal CORS oppure il CDN pretende uno user agent da browser. Il server ripiegherà su un font predefinito.
Ospita i font su un server con header CORS permissivi. Google Fonts lo fa già, ma molti font self-hosted no. Se non puoi modificare gli header, puoi incorporare i font nella pagina scaricando i file, convertendoli in data URI base64 e iniettando regole @font-face con quei data URI nei tag <style> nell'<head>. L'HTML serializzato si porta appresso le definizioni dei font e viene renderizzato correttamente ovunque venga servito.
Iframe, video e SPA
Un paio di casi limite che vale la pena tenere a mente.
Gli iframe spesso hanno dimensioni CSS fisse che non corrispondono al contenuto reale. Per iframe same-origin puoi leggere l'altezza del contenuto da contentDocument.body.scrollHeight e ridimensionare di conseguenza. Per quelli cross-origin serve un'altezza di fallback generosa.
I video in autoplay vengono catturati a metà riproduzione e mostrano un fotogramma a caso. Mettili in pausa e riportali al fotogramma 0 prima della cattura, così lo screenshot mostra il primo fotogramma.
Le applicazioni single page sono le più rognose. Le app React, Vue e Angular caricano il contenuto dinamicamente e Matomo potrebbe catturare il DOM prima che il framework abbia finito il rendering. Anche l'URL potrebbe non corrispondere a quello del router. Non c'è una soluzione unica. La cosa migliore è configurare le regole di corrispondenza URL di Matomo per le rotte della SPA e usare l'API JS di Matomo per triggerare la registrazione a rendering completato.
Risolvere tutto in un colpo con Matomo Heatmap Helper
La maggior parte dei siti reali ha più di uno di questi problemi. Sistemarli tutti a mano significa mettere le mani nella configurazione del CDN, riscrivere URL, rifare il CSS e scrivere script di cattura ad hoc.
Matomo Heatmap Helper è un'estensione gratuita e open source per Chrome e Firefox che gestisce tutti i problemi descritti sopra. Sorgente su GitHub.
In pratica: installi l'estensione, inserisci URL di Matomo e token API, scegli su quali siti attivarla. Sulle pagine che corrispondono compare una barra degli strumenti. Clicchi su "Interactive" e poi clicchi sugli elementi da sistemare: container con scroll, header sticky, sezioni con immagini mancanti. Ogni elemento selezionato prende un'icona a lucchetto.
Quando premi il pulsante screenshot, l'estensione fa il suo giro. Scarica e incorpora immagini e font cross-origin, espande gli elementi vincolati, toglie lo sticky dagli header, gestisce iframe e video, converte gli URL relativi in assoluti e chiama l'API screenshot di Matomo. Finito, annulla ogni modifica. La pagina torna esattamente com'era.
Prima di scattare uno screenshot
Checklist veloce:
- Assicurati che la pagina sia completamente renderizzata, soprattutto contenuto SPA e sezioni lazy
- Blocca i container che tagliano il contenuto o che vanno espansi
- Controlla se ci sono header sticky o fissi che potrebbero coprire il contenuto
- Verifica che immagini e font principali siano visibili
- Scatta lo screenshot e controlla che la verifica vada a buon fine
- Apri la vista heatmap e guarda il risultato prima di partire con l'analisi
Due strade
Questi problemi con gli screenshot non sono bug del tuo sito. Sono effetti collaterali di come Matomo serializza la pagina e la ri-renderizza altrove. Qualsiasi sito che usa CDN, web font, container con scroll o header sticky si troverà davanti a una combinazione di questi problemi.
Puoi risolverli a livello infrastrutturale: aggiungere header CORS, passare a URL assoluti, ristrutturare i container con overflow, gestire il posizionamento sticky durante la cattura. Se controlli il server è l'approccio giusto sul lungo periodo, ma ci vuole tempo e per alcuni problemi non esistono soluzioni pulite lato server.
Oppure li risolvi al momento della cattura con Matomo Heatmap Helper. Usi la modalità interattiva per indicare quali parti della pagina hanno bisogno di aiuto e ottieni screenshot puliti senza toccare il codice in produzione.