Se você já abriu um heatmap do Matomo e encontrou sua sidebar truncada, a metade inferior de um modal faltando, ou marcadores de clique flutuando sobre conteúdo que não parece pertencer a eles, saiba que os cliques em si estão corretos. O Matomo os registrou nas coordenadas certas. O que está quebrado é a captura de tela por baixo deles. Algum wrapper na página tem overflow: hidden, overflow: auto ou overflow: scroll definido, e o renderizador do Matomo trata tudo que fica além da borda visível desse wrapper como se não existisse. O resultado é que o heatmap mostra um recorte da página em vez da página que seus visitantes realmente viram.
A correção mais rápida é uma extensão gratuita do Chrome que mantemos chamada Matomo Heatmap Helper. Ela neutraliza os containers com overflow logo antes de cada captura, deixa o renderizador ver o documento completo e restaura os estilos originais depois. O restante deste post explica como fazer o mesmo sem a extensão, além de algumas correções permanentes que valem a pena incluir no código.
Como corrigir sem a extensão
Tem um snippet de console que resolve o problema logo antes de cada captura, e algumas correções permanentes que você pode incluir no site. Escolha o que melhor se encaixa nas suas restrições.
Liste todos os elementos com overflow restrito na página
Antes de mudar qualquer coisa, descubra quais wrappers estão cortando o conteúdo. Abra a página no Chrome, pressione F12 para abrir o DevTools, vá para o Console e cole:
// Lista todos os elementos que estão cortando conteúdo atualmente
Array.from(document.querySelectorAll('*')).filter(el => {
const s = getComputedStyle(el);
return ['hidden','auto','scroll'].includes(s.overflow)
|| ['hidden','auto','scroll'].includes(s.overflowY);
});Isso te dá a lista exata dos nós que o renderizador do Matomo vai tratar como caixas de tamanho fixo. Os suspeitos usuais são sidebars, modais, wrappers de scroll customizados em torno de <main> e antigos wrappers de clearfix com overflow: hidden por razões de layout que já não fazem sentido há anos.
A correção rápida: remover as restrições de overflow pelo console
É o snippet que colamos no console do navegador logo antes de disparar a captura do heatmap do Matomo. Ele percorre todos os elementos que estão cortando e muda o overflow e o overflow-y para visible. Quando o Matomo serializa o DOM, nada está mais escondendo conteúdo além de uma borda visível.
// Cole no console do navegador logo antes da captura.
// Transforma todos os containers com overflow da página em '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';
}
});A página vai ficar estranha por um momento. Sidebars se expandem até a altura total do conteúdo, modais se esticam além da borda do viewport, e tudo que dependia de um container com altura fixa de repente fica sem um. Tudo bem. Você está capturando o heatmap, não navegando pelo site. Atualize a página quando terminar.
Esse é o caminho rápido. Funciona para capturas únicas e os ciclos de revisão em que você precisa de uma captura limpa agora e não quer esperar por uma mudança de código. Para qualquer coisa que você vai capturar com regularidade, use uma das correções permanentes abaixo.
Correção permanente via CSS com escopo para o modo de captura
A solução mais limpa quando você controla o stylesheet é um override exclusivo para heatmap que desativa todos os containers com overflow assim que o tracker do Matomo é carregado. Um bloco CSS, uma linha de JavaScript, e está resolvido.
/* Edite os seletores para corresponder aos wrappers do seu site */
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;
}// Adicione ao seu site. Ativa a classe sempre que o tracker do Matomo está na página.
if (window._paq) document.documentElement.classList.add('heatmap-mode');Assim o override só entra em ação nas páginas onde o Matomo está sendo carregado mesmo, o que é perfeito para uma revisão de heatmap e invisível para o restante do seu tráfego. Se preferir um escopo mais restrito, condicione a um query param (?heatmap=1) ou a um stylesheet separado incluído apenas na cópia de staging que você aponta para o Matomo.
Remova o container de scroll aninhado de vez
Se sua página tem overflow: auto em <main> ou algum outro wrapper por razões de "scrollytelling", a correção arquitetural é removê-lo e deixar o documento rolar. O renderizador do Matomo consegue reproduzir o scroll do documento, mas não consegue reproduzir a posição de scroll de um container aninhado com overflow: auto. Você também ganha uma UX mobile melhor (o iOS Safari tem suas próprias opiniões sobre containers de scroll aninhados) e a acessibilidade melhora porque o scroll por teclado e a navegação por leitor de tela passam a funcionar do jeito que os usuários esperam.
É uma mudança maior do que o override de CSS, mas é a que impede o problema de voltar na próxima vez que alguém adicionar uma nova seção ao layout.
Substitua o overflow: hidden do clearfix por display: flow-root
Antigos wrappers de clearfix com overflow: hidden eram um contorno para conter filhos flutuantes. display: flow-root faz a mesma coisa sem cortar nada, e é seguro usar em todos os navegadores que valem a pena suportar desde 2018.
/* Edite o seletor para corresponder ao seu wrapper de clearfix */
.row-with-floats {
display: flow-root;
}Mesmo comportamento de contenção, sem corte, e você para de brigar com a captura de tela. O jeito mais rápido de encontrar candidatos é fazer um grep no seu CSS por overflow: hidden e verificar se cada ocorrência realmente tem a intenção de cortar alguma coisa. Na maioria das vezes, não.
Uma nota sobre o trade-off
Qualquer que seja a correção permanente que você escolher, limite o override com escopo (uma classe, um query param, um stylesheet exclusivo para heatmap) em vez de alterar os estilos ao vivo para todos. Seus visitantes estão vendo o layout que você projetou para eles, e o modal que deveria rolar dentro da própria caixa deve continuar fazendo isso para eles. O override só precisa existir para o renderizador que o Matomo aponta para a página.
Por que o Matomo não consegue renderizar seus containers com overflow
A captura de tela do Matomo é um processo em duas etapas. Primeiro, o tracker serializa seu DOM ao vivo em HTML e o envia. Depois, seu servidor Matomo re-renderiza esse HTML em um viewport fixo para produzir a captura que você vê na visualização do heatmap. Sem sessão de navegador, sem posição de scroll carregada do visitante, sem ajustes de layout via JavaScript. Só um arquivo HTML sendo renderizado a frio a partir de um IP diferente.
O renderizador consegue reproduzir o scroll do documento, que é por isso que páginas longas capturam bem. O que ele não consegue reproduzir é a posição de scroll interna de um container overflow: auto aninhado, porque isso fica no navegador do visitante e nunca entra no DOM serializado. Quando o renderizador encontra um wrapper overflow: hidden, ele faz o que qualquer navegador faz e corta. O resultado é uma captura que parece com o recorte visível da página em um momento específico, com todo o resto sumido.
As coordenadas de clique pioram a situação. O Matomo registra cliques em relação ao documento, não em relação à posição de scroll interna de qualquer container que o usuário estava rolando. Um clique no terceiro item de uma sidebar rolável é armazenado na coordenada y que ele ocupava no momento do clique. Quando o renderizador captura a sidebar com scroll-top zero, essa coordenada y agora pertence ao primeiro item. O marcador plota lá. O clique parece ter caído no link errado.
O que está falhando de verdade
Alguns padrões que continuamos encontrando:
- Sidebars e modais com suas próprias barras de rolagem. O wrapper tem uma altura fixa e
overflow: auto, a lista interna é mais alta, e só a parte visível no momento da captura entra na imagem. - Páginas com "scrollytelling" com
overflow: autoem<main>ou um wrapper similar. O body não rola, o elemento interno rola, e o heatmap captura o equivalente a um viewport de conteúdo. - Antigos wrappers de clearfix com
overflow: hiddenque não têm a intenção real de cortar nada. Foram feitos para conter floats. Ainda cortam, e ainda derrubam conteúdo da captura. - Menus dropdown customizados ou acordeões que animam cortando o conteúdo com
overflow: hiddenmais uma transição de altura. O estado fechado é o que o Matomo vê. - CSS
maskouclip-pathem um container. Propriedade diferente, mesmo efeito na captura. A correção é a mesma: desative no modo de captura.
Se o seu heatmap está faltando conteúdo ou os marcadores de clique não se alinham com os elementos que você esperaria, você está enfrentando pelo menos um desses. Muitas vezes mais de um na mesma página.
Essa é também a mesma família de problema que quebra fontes, imagens e headers sticky na mesma captura. Escrevemos um post mais completo sobre capturas de tela quebradas no heatmap do Matomo que aborda o resto, e posts separados sobre por que as fontes não carregam e por que as imagens não carregam, já que esses aparecem quase com a mesma frequência.
O que faríamos na prática
Se você controla o stylesheet, inclua o override exclusivo para heatmap. Um bloco CSS com escopo para uma classe que você ativa quando o tracker do Matomo é carregado. É o menor diff que resolve o problema de forma permanente e não toca no que os visitantes veem.
Se o layout tem um container de scroll aninhado que já estava te incomodando por outros motivos também, use a correção arquitetural e deixe o documento rolar. Você vai se livrar desse problema em todas as capturas de heatmap futuras, e seus usuários mobile vão agradecer.
Se nenhuma das opções é viável (sem acesso ao stylesheet, widgets de terceiros que você não pode reestilizar, um CMS que não deixa você incluir CSS customizado), a extensão Chrome Matomo Heatmap Helper é o que usamos em sites de clientes onde não podemos mudar a stack. Ela percorre os mesmos containers com overflow que o snippet encontra, os neutraliza para a captura e os restaura depois, deixando a página intacta para o próximo visitante. Gratuita, open source, código no GitHub.
O Martez é o projeto maior do qual a extensão surgiu. Ele conecta o Matomo com Meta Ads e Google Ads para que ROAS, CLV e atribuição fiquem ao lado da sua análise web em vez de numa planilha separada. Está em beta privado. Entre na lista de espera se isso for relevante para você.
Na maioria das vezes, é só uma mudança de stylesheet. Vale fazer uma vez.