Svelte
Svelte a un wrapper dédié : @vskstudio/takt-svelte (composant, action, web component), bâti sur le cœur @vskstudio/takt-core.
Le cœur est une dépendance peer : installe les deux paquets. Depuis la 0.8.0, le wrapper exige @vskstudio/takt-core >=0.10.0.
pnpm add @vskstudio/takt-svelte @vskstudio/takt-core
# ou : npm install @vskstudio/takt-svelte @vskstudio/takt-core
# ou : yarn add @vskstudio/takt-svelte @vskstudio/takt-core
# ou : bun add @vskstudio/takt-svelte @vskstudio/takt-core Le package expose trois styles d’intégration :
@vskstudio/takt-svelte: le composant<Takt>+ le hookuseTakt(), et les fonctions de consentementoptOut()/optIn()/isOptedOut()réexportées du cœur.@vskstudio/takt-svelte/actions: l’actionuse:taktEvent+ les fonctionsinit/track/pageview/optOut/optIn/isOptedOutréexportées du cœur.@vskstudio/takt-svelte/element: le web component<takt-analytics>pour du HTML pur.
<Takt> et <takt-analytics> sont sûrs au SSR : ils n'initialisent qu'au montage, côté navigateur. Le init() du sous-chemin /actions touche history dès l'appel. L'exécuter dans le <script> d'un composant SvelteKit le fait tourner au rendu serveur et lève ReferenceError: history is not defined. Appelle-le depuis onMount.Cette page est la référence des options. Pour l’intégration de bout en bout dans une application SvelteKit et son piège principal (useTakt() appelé dans le <script> d’un composant, donc avant le montage de <Takt>) : voir le guide analytics sans cookie dans une application SvelteKit.
Composant <Takt> + useTakt()
Place <Takt> une fois (typiquement dans +layout.svelte) : il initialise l’instance au montage, émet le pageview initial et câble la navigation SPA. Le composant ne rend aucun balisage. C’est un point de câblage, pas un conteneur, et il n’a donc pas d’enfants. useTakt() récupère l’instance depuis n’importe où dans l’application (un store de module sert de relais), pas seulement sous <Takt>.
<!-- +layout.svelte -->
<script>
import { Takt } from '@vskstudio/takt-svelte'
</script>
<Takt domain="exemple.fr" outbound files />
<slot /> Appelle useTakt() dans le gestionnaire, pas dans le <script> : le <script> s’exécute à l’initialisation du composant, donc avant le onMount de <Takt>. Une instance capturée là serait le no-op définitif, et tous les events partiraient dans le vide.
<script>
import { useTakt } from '@vskstudio/takt-svelte'
</script>
<button onclick={() => useTakt().track('Signup', { props: { plan: 'pro' } })}>
S'inscrire
</button>
<button
onclick={() =>
useTakt().track('Purchase', {
props: { plan: 'pro' },
revenue: { amount: '29', currency: 'EUR' }
})}
>
Acheter
</button> Props du composant <Takt> :
| Prop | Type | Défaut | Rôle |
|---|---|---|---|
domain | string | location.hostname | Identifiant du site |
endpoint | string | https://taktlytics.com/api/event | URL d’ingestion. Passe /api/event pour un proxy first-party same-origin. |
scriptOrigin | string | aucun | Origine first-party dont dériver l’endpoint (l’origine suivie de /api/event). endpoint l’emporte. |
outbound | boolean | false | Suit les liens sortants |
files | boolean \| string[] | false | Suit les téléchargements (liste d’extensions optionnelle) |
spa | boolean | true | Suit la navigation client (pageviews auto) |
track404 | boolean | false | Signale un événement 404 sur les pages d’erreur (marqueur [data-takt-404] / <meta name="takt:404">, ou statut HTTP 404). |
tagged | boolean | false | Suit automatiquement les éléments [data-takt-event] |
respectDnt | boolean | true | Respecte Do Not Track |
excludeLocalhost | boolean | true | Ignore localhost / IP privées |
enabled | boolean | true | Interrupteur général : false coupe toute mesure |
sampleRate | number | 1 | Fraction de sessions échantillonnées (0 à 1) |
trackQuery | boolean | false | Conserve la query string dans les URL |
queryParams | string[] | aucun | Paramètres conservés quand trackQuery est false (liste blanche) |
exclude | string[] | aucun | Préfixes de chemin jamais suivis. Bornés au segment : /app couvre /app et /app/… mais pas /application. |
scrubUrl | (url: string) => string | aucun | Transforme chaque URL avant envoi (page, referrer, url des liens sortants et des téléchargements, path des 404) |
debug | boolean | false | Trace chaque payload dans la console avant l’envoi |
redactRoutes | string[] | aucun | Motifs de routes sensibles envoyés à la place du chemin réel, ex. ['/verify/[token]'] (voir Masquage de routes) |
redactUndecodablePaths | boolean | true | Non exposée par ce wrapper : se règle sur le SDK core (init() / createTakt()), voir Chemins illisibles |
routeTemplates | boolean | false | Envoie chaque page sous la forme de son gabarit de route ; exige routeTemplate |
routeTemplate | () => string \| null \| undefined | aucun | Renvoie le gabarit de la route courante, ex. () => page.route.id avec SvelteKit |
enabled, sampleRate, trackQuery, queryParams, exclude, scrubUrl) sont disponibles en props, sans passer par le sous-chemin /actions, tout comme debug depuis la 0.7.0.useTakt() ne lève pas : appelé avant le montage de <Takt> ou pendant le SSR, il renvoie une instance no-op et avertit une fois en console (useTakt() called before <Takt /> mounted). Ce message est le symptôme du piège ci-dessus. Les appels de consentement font exception : ils agissent réellement, voir Consentement.
Masquage de routes
La query string est retirée par défaut, mais le chemin part en clair : /verify/abc123 transmet le jeton. redactRoutes liste les routes sensibles, et un chemin qui correspond part sous la forme de son motif. Tous les autres chemins gardent leur valeur réelle, les statistiques par page restent intactes.
<Takt domain="exemple.fr" redactRoutes={['/verify/[token]', '/reset/[code]', '/invoices/[id].pdf']} /> Les motifs acceptent la syntaxe SvelteKit ([param], [[optionnel]], [...reste], (groupe)) ainsi que :param, :param?, * et **. La règle couvre l’URL de la page, le referrer du même site, la destination des téléchargements et le chemin des 404.
Pour une application entièrement privée, routeTemplates envoie chaque page sous la forme de son gabarit : /blog/bonjour devient /blog/[slug]. Le package ne dépend pas de SvelteKit, tu lui passes donc le résolveur. Avec SvelteKit, lis-le depuis page.route.id :
<!-- +layout.svelte -->
<script>
import { page } from '$app/state'
import { Takt } from '@vskstudio/takt-svelte'
</script>
<Takt domain="exemple.fr" routeTemplates routeTemplate={() => page.route.id} /> Les groupes de route comme (marketing) sont retirés par le cœur : /(marketing)/blog/[slug] part comme /blog/[slug]. Quand le résolveur renvoie null (aucune route trouvée), redactRoutes s’applique quand même, sinon le chemin réel part. Sur un site public, ce mode fusionne tous les articles en une seule ligne : préfère redactRoutes. init() du sous-chemin /actions accepte les mêmes options. Détails dans Vie privée.
Consentement
optOut, optIn et isOptedOut sont exportés depuis la racine du package (et depuis ./actions). Ils n’ont besoin d’aucune instance : une bannière de consentement peut enregistrer le choix du visiteur avant le montage de <Takt>, et l’instance créée ensuite le respecte. Sur l’instance no-op, useTakt().optOut(), useTakt().optIn() et useTakt().isOptedOut() délèguent aussi à ces fonctions.
<script>
import { optOut, optIn, isOptedOut } from '@vskstudio/takt-svelte'
let optedOut = $state(isOptedOut())
function toggle(event) {
if (event.currentTarget.checked) optIn()
else optOut()
optedOut = isOptedOut()
}
</script>
<label>
<input type="checkbox" checked={!optedOut} onchange={toggle} />
Mesure d'audience
</label> isOptedOut() lit le localStorage : sur un composant rendu côté serveur, appelle-le dans le navigateur (onMount ou un gestionnaire d’événement).
Action use:taktEvent
Sans composant, initialise toi-même via init(), puis attache taktEvent à un élément cliquable. init() doit être appelé depuis onMount : au niveau du <script>, il s’exécuterait au rendu serveur et lèverait ReferenceError: history is not defined.
<script>
import { onMount } from 'svelte'
import { init, taktEvent } from '@vskstudio/takt-svelte/actions'
onMount(() => init({ domain: 'exemple.fr', sampleRate: 0.5, trackQuery: false }))
</script>
<button use:taktEvent={{ name: 'Signup', props: { plan: 'pro' } }}>
S'inscrire
</button>
<button use:taktEvent={{ name: 'Purchase', revenue: { amount: '29', currency: 'EUR' } }}>
Acheter
</button> L’action est réactive : si les paramètres changent, les clics suivants utilisent les nouvelles valeurs. Le listener est retiré à la destruction de l’élément.
Web component <takt-analytics>
Pour du HTML pur ou un framework non-Svelte, importe l’élément (auto-enregistré) :
<script type="module">
import '@vskstudio/takt-svelte/element'
</script>
<takt-analytics domain="exemple.fr" outbound files></takt-analytics> Les attributs miroir des props :
- Drapeaux (présence = actif, valeur ignorée) :
outbound,files,track-404,tagged. - Actifs par défaut, mets
="false"pour les couper :spa,respect-dnt,exclude-localhost. Les graphies historiques en un motrespectdntetexcludelocalhostrestent acceptées. - Valeurs :
domain,endpoint,script-origin,enabled,sample-rate,track-query,debug(lu seulement si l’attribut est présent), ainsi quequery-params,excludeetredact-routesqui prennent une liste séparée par des virgules (redact-routes="/verify/[token],/reset/:code").
routeTemplates et routeTemplate n’ont pas d’attribut : l’élément n’a pas de routeur. files ne prend pas de liste d’extensions ici, et scrubUrl n’a pas d’équivalent : ce sont des fonctions et des tableaux que le composant Svelte reçoit en props, hors de portée d’un attribut HTML.