Framework recipes
Drop-in setup for React, Next.js, Vue, Svelte, and other JS frameworks.
The browser SDK (@millimetric/track) is framework-agnostic — it's just init, track, identify, page, flush. This page collects the small, copy-paste-ready integrations for the frameworks people actually use.
If your framework isn't listed, the pure-JS browser snippet Just Works on any HTML page.
Sub-recipes
Common pattern across all of them
Three things, in order:
Init once — at the top of your app, with your
pk_*key.Identify on auth — when you know who the visitor is.
Track on intent — buttons, conversions, the things you'd put in a funnel.
Auto-pageviews (including SPA navigations) are on by default; you usually don't have to call page() yourself.
Where to put the key
Vite (React/Vue/Svelte)
VITE_AOA_KEY
import.meta.env.VITE_AOA_KEY
Next.js
NEXT_PUBLIC_AOA_KEY
process.env.NEXT_PUBLIC_AOA_KEY
Nuxt
NUXT_PUBLIC_AOA_KEY
useRuntimeConfig().public.aoaKey
SvelteKit
PUBLIC_AOA_KEY
import { PUBLIC_AOA_KEY } from "$env/static/public"
The pk_* key is browser-safe — it's origin-allowlisted on the server. Never expose sk_* or rk_* to the browser.
Anti-patterns
Calling
init()in a render function. Init is idempotent but inits-per-render is wasteful. Wrap inuseEffect(React) /onMount(Svelte) /mounted()(Vue).Tracking inside
useEffectcleanup. The cleanup runs on unmount and on every re-render — easy to over-track. Track on the user action (onClick), not on the effect lifecycle.Calling
flush()synchronously in render. It returns a promise; awaiting it in render breaks SSR.Setting
user_idfrom your URL. Useidentify(user.id)once after auth resolves; don't passuser_idper-call.
Last updated
Was this helpful?