takt

Astro

Astro a une intégration dédiée : @vskstudio/takt-astro, bâtie sur le cœur @vskstudio/takt-core. Elle injecte un petit runtime navigateur qui boote Takt, émet le pageview initial et suit la navigation client — y compris les View Transitions d'Astro.

pnpm add @vskstudio/takt-astro @vskstudio/takt-core

@vskstudio/takt-core (>=0.8.1) et astro (>=4) sont des peer dependencies. Le runtime est sûr au SSR / prerender : il est gardé par un test typeof window et ne s’exécute que dans le navigateur.

Cette page est la référence des options. Pour l’intégration de bout en bout et son piège principal — l’écouteur astro:page-load ajouté en trop, qui double chaque page vue — voir le guide analytics sans cookie sur un site Astro.

Choisis une seule des deux voies ci-dessous — pas les deux. Les deux bootent l'instance par défaut du cœur derrière le même drapeau window.__takt : la seconde voie chargée ne réinitialise rien, elle ne fait strictement rien. Tu n'aurais donc pas de double comptage, juste un second script embarqué pour rien.

Intégration (recommandé)

Ajoute takt() à la liste integrations de ta config Astro :

// astro.config.mjs
import { defineConfig } from 'astro/config'
import takt from '@vskstudio/takt-astro'

export default defineConfig({
  integrations: [takt({ domain: 'exemple.fr' })]
})

Composant <Takt />

Pour un contrôle par layout, place le composant dans le <head> d’un layout :

---
import Takt from '@vskstudio/takt-astro/Takt.astro'
---
<head>
  <Takt domain="exemple.fr" />
</head>

L’intégration et le composant acceptent les mêmes options, à une exception près : scrubUrl est une fonction et n’est acceptée que par l’intégration (voir la note sous le tableau).

OptionTypeDéfautRôle
domainstringlocation.hostnameIdentifiant du site
endpointstringhttps://taktlytics.com/api/eventURL d’ingestion ; mets /api/event pour un proxy first-party same-origin
scriptOriginstringOrigine dont dériver l’endpoint ({origin}/api/event), pour un domaine custom proxifié ; endpoint reste prioritaire
outboundbooleanfalseSuit les liens sortants
filesbooleanfalseSuit les téléchargements
spabooleantrueSuit la navigation client (mappé sur l’option auto du cœur)
track404booleanfalseSignale un événement 404 sur les pages d’erreur (marqueur [data-takt-404] / <meta name="takt:404">, ou statut HTTP 404).
taggedbooleanfalseSuit les éléments porteurs de data-takt-event
respectDntbooleantrueRespecte Do Not Track
excludeLocalhostbooleantrueIgnore localhost / IP privées
enabledbooleantrueInterrupteur général : à false, plus aucun event
sampleRatenumber1Fraction de visiteurs suivis, de 0 à 1
trackQuerybooleanfalseEnvoie l’URL complète au lieu d’en retirer query et hash
queryParamsstring[]Liste blanche de paramètres conservés quand trackQuery est off
excludestring[]Préfixes de chemin jamais suivis, ex. ['/app','/compte'] (bornés au segment : /app couvre /app et /app/…, pas /application)
scrubUrl(url: string) => stringIntégration seulement. Réécrit chaque URL avant envoi
scrubUrl est une fonction : elle est sérialisée à la compilation via toString() puis réévaluée dans le navigateur. Elle doit donc être autonome — aucune variable de closure ni référence au scope englobant — et ne jamais être construite à partir d'entrées utilisateur. Le composant <Takt />, lui, sérialise sa config en îlot de données JSON, qui ne peut pas transporter de fonction : lui passer scrubUrl lève une erreur à la compilation plutôt que de l'ignorer en silence.

View Transitions

Le ClientRouter d’Astro effectue plusieurs opérations d’historique par navigation (un replaceState de restauration de scroll, puis un pushState). Le patch d’historique du cœur compterait donc en double. L’intégration l’écarte : elle initialise le cœur avec auto: false, ce qui désactive à la fois le patch pushState/replaceState et le pageview de boot.

Le runtime pilote donc les pageviews depuis le cycle de vie d’Astro :

  • un pageview initial explicite au boot du script — ce qui couvre aussi les sites MPA classiques, où le script est réexécuté à chaque chargement de page et où astro:after-swap ne se déclenche jamais ;
  • puis un pageview par événement astro:after-swap, émis exactement une fois par navigation du ClientRouter (échanges de DOM des View Transitions et retour/avant compris), quand spa est actif.

Chaque navigation est ainsi comptée exactement une fois.

N'ajoute pas de listener astro:page-load pour suivre les pages : le runtime enregistre déjà son propre astro:after-swap. Le tien en installerait un second et compterait chaque navigation deux fois.
Corollaire : puisque le patch d'historique du cœur est désactivé, un history.pushState que tu pilotes à la main — filtres, onglets, pagination hors ClientRouter — ne déclenche aucun astro:after-swap, donc aucun pageview. C'est le seul cas où appeler pageview() toi-même est la bonne réponse.

Events personnalisés

Les fonctions du cœur sont réexportées par commodité :

import { track } from '@vskstudio/takt-astro'

track('Signup', { revenue: { amount: '9.00', currency: 'USD' } })

track/pageview/optOut/optIn s’exécutent côté navigateur — appelle-les depuis un <script> client ou un composant d’un framework UI hydraté.