Este tutorial demonstra como acompanhar o uso da sua extensão usando o Google Analytics. Há um exemplo ativo do Google Analytics 4 no GitHub (em inglês), em que google-analytics.js
inclui todo o código relacionado ao Google Analytics.
Requisitos
Este tutorial presume que você conheça a criação de extensões do Chrome. Se você precisar de informações sobre como escrever uma extensão, leia o Tutorial de início.
Você também precisa configurar uma conta do Google Analytics 4 para acompanhar sua extensão. Ao configurar a conta, você pode usar qualquer valor no campo "URL do site", já que sua extensão não terá um URL próprio.
Uso do Measurement Protocol do Google Analytics
Desde o Manifest V3, as extensões do Chrome não podem executar código hospedado remotamente. Isso significa que você precisa usar o Measurement Protocol do Google Analytics para acompanhar eventos de extensão. Com o Measurement Protocol, você pode enviar eventos diretamente aos servidores do Google Analytics usando solicitações HTTP. Uma vantagem dessa abordagem é que ela permite enviar eventos de análise de todos os lugares da extensão, incluindo o service worker.
Configurar credenciais de API
A primeira etapa é conseguir um api_secret
e um measurement_id
. Siga a documentação do Measurement Protocol para saber como acessá-las na sua conta do Google Analytics.
Gerar um client_id
A segunda etapa é gerar um identificador exclusivo para um dispositivo/usuário específico, o client_id
. O ID precisa permanecer o mesmo, desde que a extensão esteja instalada no navegador do usuário. Pode ser uma string arbitrária, mas precisa ser exclusiva para o cliente. É possível gerar um chamando self.crypto.randomUUID()
. Armazene o client_id
no chrome.storage.local
para que ele permaneça igual enquanto a extensão estiver instalada.
O uso de chrome.storage.local
exige a permissão storage
no arquivo de manifesto:
manifest.json:
{
…
"permissions": ["storage"],
…
}
Em seguida, use chrome.storage.local
para armazenar o client_id
:
async function getOrCreateClientId() {
const result = await chrome.storage.local.get('clientId');
let clientId = result.clientId;
if (!clientId) {
// Generate a unique client ID, the actual value is not relevant
clientId = self.crypto.randomUUID();
await chrome.storage.local.set({clientId});
}
return clientId;
}
Enviar um evento do Analytics
Com as credenciais da API e o client_id
, você pode enviar um evento para o Google Analytics usando uma solicitação fetch
:
const GA_ENDPOINT = 'https://www.google-analytics.com/mp/collect';
const MEASUREMENT_ID = `G-...`;
const API_SECRET = `...`;
fetch(
`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
{
method: 'POST',
body: JSON.stringify({
client_id: await getOrCreateClientId(),
events: [
{
name: 'button_clicked',
params: {
id: 'my-button',
},
},
],
}),
}
);
Isso envia um evento button_clicked
, que vai aparecer no seu relatório de eventos do Google Analytics. Se você quiser ver seus eventos no Relatório de tempo real do Google Analytics, precisará fornecer dois parâmetros adicionais: session_id
e engagement_time_msec
.
Use os parâmetros recomendados session_id
e engagement_time_msec
Tanto session_id
quanto engagement_time_msec
são parâmetros recomendados ao usar o Measurement Protocol do Google Analytics porque são necessários para que a atividade do usuário seja mostrada em relatórios padrão, como o Relatório de tempo real.
Uma session_id
descreve um período em que o usuário interage continuamente com sua extensão. Por padrão, uma sessão termina após 30 minutos de inatividade do usuário. Não há limite para a duração dela.
Diferentemente dos sites normais nas extensões do Chrome, não há uma noção clara de uma sessão de usuário. Portanto, é preciso definir o significado de uma sessão de usuário na sua extensão. Por exemplo, cada nova interação do usuário pode ser uma nova sessão. Nesse caso, você pode simplesmente gerar um novo ID de sessão para cada evento (ou seja, usando um carimbo de data/hora).
O exemplo a seguir demonstra uma abordagem que esgotará o tempo limite de uma nova sessão após 30 minutos sem eventos relatados. Esse tempo pode ser personalizado para se adequar melhor ao comportamento do usuário da sua extensão. O exemplo usa chrome.storage.session
para armazenar a sessão ativa enquanto o navegador está em execução. Junto com a sessão, armazenamos a última vez em que um evento foi disparado. Dessa forma, podemos saber se a sessão ativa expirou:
const SESSION_EXPIRATION_IN_MIN = 30;
async function getOrCreateSessionId() {
// Store session in memory storage
let {sessionData} = await chrome.storage.session.get('sessionData');
// Check if session exists and is still valid
const currentTimeInMs = Date.now();
if (sessionData && sessionData.timestamp) {
// Calculate how long ago the session was last updated
const durationInMin = (currentTimeInMs - sessionData.timestamp) / 60000;
// Check if last update lays past the session expiration threshold
if (durationInMin > SESSION_EXPIRATION_IN_MIN) {
// Delete old session id to start a new session
sessionData = null;
} else {
// Update timestamp to keep session alive
sessionData.timestamp = currentTimeInMs;
await chrome.storage.session.set({sessionData});
}
}
if (!sessionData) {
// Create and store a new session
sessionData = {
session_id: currentTimeInMs.toString(),
timestamp: currentTimeInMs.toString(),
};
await chrome.storage.session.set({sessionData});
}
return sessionData.session_id;
}
O exemplo a seguir adiciona session_id
e engagement_time_msec
à solicitação de evento de clique do botão anterior. Para engagement_time_msec
, é possível fornecer um valor padrão de 100 ms
.
const GA_ENDPOINT = "https://www.google-analytics.com/mp/collect";
const MEASUREMENT_ID = `G-...`;
const API_SECRET = `...`;
const DEFAULT_ENGAGEMENT_TIME_IN_MSEC = 100;
fetch(
`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
{
method: "POST",
body: JSON.stringify({
client_id: await getOrCreateClientId(),
events: [
{
name: "button_clicked",
params: {
session_id: await this.getOrCreateSessionId(),
engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC,
id: "my-button",
},
},
],
}),
}
);
O evento aparece da seguinte forma no Relatório de tempo real do Google Analytics.
Acompanhar visualizações de página em pop-up, painel lateral e páginas de extensão
O Measurement Protocol do Google Analytics é compatível com um evento page_view
especial para acompanhar visualizações de página. Use-o para acompanhar os usuários que acessam suas páginas pop-up, o painel lateral ou a página de uma extensão em uma nova guia. O evento page_view
também requer os parâmetros page_title
e page_location
. O exemplo a seguir dispara um evento de visualização de página no evento load
do documento para um pop-up de extensão:
popup.js:
window.addEventListener("load", async () => {
fetch(`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
{
method: "POST",
body: JSON.stringify({
client_id: await getOrCreateClientId(),
events: [
{
name: "page_view",
params: {
session_id: await getOrCreateSessionId(),
engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC,
page_title: document.title,
page_location: document.location.href
},
},
],
}),
});
});
O script popup.js
precisa ser importado no arquivo html do pop-up e ser executado antes de qualquer outro script:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Analytics Demo Popup</title>
<script src="./popup.js" type="module"></script>
</head>
<body>
<h1>Analytics Demo</h1>
</body>
</html>
A visualização pop-up aparece como qualquer outra visualização de página no Relatório de tempo real do Google Analytics:
Rastrear eventos de análise em service workers
Com o Measurement Protocol do Google Analytics, é possível acompanhar eventos de análise de funcionários de serviços de extensão. Por exemplo, detectando o unhandledrejection event
no service worker, você pode registrar todas as exceções não identificadas no service worker no Google Analytics, o que pode ser muito útil para depurar problemas que os usuários podem relatar.
service-worker.js:
addEventListener("unhandledrejection", async (event) => {
`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
{
method: "POST",
body: JSON.stringify({
client_id: getOrCreateClientId(),
events: [
{
// Note: 'error' is a reserved event name and cannot be used
// see https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=gtag#reserved_names
name: "extension_error",
params: {
session_id: await this.getOrCreateSessionId(),
engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC,
message: error.message,
stack: error.stack,
},
},
],
}),
}
});
Agora o evento de erro aparece nos seus relatórios do Google Analytics:
Depuração
O Google Analytics oferece dois recursos úteis para depurar eventos de análise na sua extensão:
- Um endpoint de depuração especial
https://www.google-analytics.com**/debug**/mp/collect
que informa erros nas definições dos seus eventos. - O Relatório em tempo real do Google Analytics que mostra os eventos conforme eles chegam.