Enviar eventos de analítica
Um callback, cinco eventos, nenhum fornecedor — liga as interações dos leitores do duxt à analítica que já tens a correr.
O duxt comunica o que os leitores fazem com um site de documentação — pesquisar, copiar um comando, experimentar um endpoint, responder «Esta página foi útil?» — a uma única função que escreves. Não traz nenhum fornecedor, nenhum SDK e nenhum script, e um site que não tenha escrito essa função não comunica nada nem descarrega seja o que for a mais.
Não há destino por omissão, porque uma camada de documentação não pode escolher
um para os leitores de outra pessoa. Sem duxt.analytics.track, cada uma das
chamadas abaixo chega a uma função ausente e para por aí.
Passos
- Escreve o callback. Vive em
app.config.ts, ao lado do resto da tua configuração do duxt, e recebe um evento por cada interação:export default defineAppConfig({ duxt: { analytics: { track(event) { // `event.name` é o discriminante; `event.context` diz em que página, // locale, fonte e versão isto aconteceu. console.log(event.name, event.context.path); } } } });
O callback corre apenas no browser. Uma compilação e uma pré-renderização nunca o chamam, por isso uma renderização estática não te enche a analítica com páginas que um rastreador abriu. - Envia-o para onde a tua analítica já vive. O que quer que o teu
fornecedor exponha — um SDK que já esteja na página, ou uma rota tua para que
o browser do leitor nunca fale com um terceiro que não escolheste:
export default defineAppConfig({ duxt: { analytics: { track(event) { const { name, context, ...properties } = event; // O teu fornecedor, os teus nomes de propriedades, a tua barreira de // consentimento. window.plausible?.(name, { props: { ...context, ...properties } }); } } } });
O duxt não define nenhum cookie, não guarda nada, não retém nada e não mostra
nenhum aviso de consentimento — não tem nada por que perguntar, porque nada
sai da página a não ser através da tua função. Isso também quer dizer que a
barreira é tua: se a tua política de privacidade exigir consentimento antes
de isto chegar a um fornecedor, verifica-o dentro do track e sai cedo.
- Escolhe os eventos que queres e deixa cair os restantes. A união é
fechada, por isso um
switchcobre-a de forma exaustiva e tudo o que não nomeares simplesmente não é enviado:
track(event) {
if (event.name === 'search' && event.results === 0) {
// O único relatório que um site de documentação quase sempre quer: um
// termo que alguém procurou e a que o site não soube responder.
report('docs-search-miss', { query: event.query, ...event.context });
}
}
- Verifica que chega um evento, com o contexto que esperavas — sob um prefixo de versão e de locale, e não apenas no URL nu.
Os eventos
Cada evento tem um name, os seus próprios campos e um context.
name | Emitido quando | Transporta |
|---|---|---|
search | Uma consulta não vazia assenta, depois do debounce — incluindo uma que não encontrou nada | query, results, approximate |
search-result | Um leitor abre um resultado | query, rank, to, collection |
copy | Um exemplo de código da camada é copiado | kind, language, manager, sample |
api-request | Um pedido do cliente de ensaio termina | operation, method, path, outcome, statusClass, duration |
feedback | Um leitor responde a «Esta página foi útil?» | helpful |
search dispara uma vez por consulta assente, não por tecla premida: o
debounce descarta o que ninguém acabou de escrever, e um resultado substituído
por outro mais recente nunca é comunicado, porque o leitor nunca chegou a vê-lo.
copy cobre os exemplos de código da própria camada — uma cerca, um
::code-group, um bloco ::package-managers, uma amostra de pedido no cliente
de ensaio — com kind a dizer qual. «Copiar a página como Markdown» não
pertence a esta família e não emite nada: é a página, não um exemplo dentro
dela.
api-request descreve a operação tal como o documento OpenAPI a declara.
path é o modelo (/pets/{id}), nunca o URL que foi chamado.
O contexto
| Campo | Notas |
|---|---|
path | O caminho da documentação, sem o prefixo de locale, a query string nem o fragmento |
locale | O locale em que a página foi lida |
source | De que fonte veio a página — ausente num site com uma só fonte |
version | Que versão — ausente onde a fonte só tem uma |
O que nunca é enviado
Esta lista é o sentido da funcionalidade, por isso vale a pena dizê-la sem rodeios. Nenhum evento transporta:
- uma credencial, um cabeçalho ou um token de API;
- um corpo de pedido ou de resposta, nem um URL de pedido concreto;
- o texto que foi copiado;
- o conteúdo apresentado de um resultado de pesquisa;
- um identificador de browser, de sessão ou de leitor, seja de que tipo for;
- a query string ou o fragmento do caminho da própria página.
O duxt também nunca transmite, retém nem persiste nada por si. Não há fila, nem repetição, nem armazenamento, nem chamada de rede na camada: a tua função é a única coisa que alguma vez sai da página.
O teu callback nunca é esperado, e o que quer que ele lance ou com que rejeite é engolido — um fornecedor em baixo não pode levar consigo a pesquisa, a cópia, a opinião ou o pedido.
Opiniões da página, pelos dois caminhos
feedback é a mesma resposta que o DuxtPageFeedback sempre emitiu. O evento
@feedback do componente e o seu slot por omissão não mudaram, por isso
envolvê-lo continua a funcionar e nenhum dos
caminhos precisa do outro — usa o callback de analítica se quiseres um destino
único para tudo, e o invólucro se só as opiniões forem para um sítio próprio.
Lista de verificação
-
duxt.analytics.trackestá definido, e não foi preciso mais nada para o ligar - O destino é teu — um fornecedor que escolheste, ou uma rota tua
- O consentimento é verificado dentro do
track, se a tua política o pedir - Chegou um evento com o caminho, o locale, a fonte e a versão que esperavas
- Nada do que reencaminhas identifica o leitor