SvelteKit Analytics: Tracking a Framework That Ships Less JS
SvelteKit apps deserve a tracker that matches their weight class. Setup in app.html, SPA navigation tracking, and events from Svelte components.
Svelte's compiler-first philosophy produces some of the lightest apps on the web — which makes the average analytics bundle look especially absurd next to them. Adding 90 KB of tracking to a 40 KB SvelteKit app inverts your engineering values in one script tag. The setup below keeps the measurement proportional to the thing measured: 1.1 KB, cookieless, one tag.
Installation in app.html
<!-- src/app.html -->
<head>
%sveltekit.head%
<script
defer
src="https://clycyo.com/tracker.js"
data-tracking-id="YOUR_TRACKING_ID"
></script>
</head>app.html wraps every page in every rendering mode — SSR, prerendered, SPA — so this is the one place the tag belongs. SvelteKit's client-side router drives navigation through the History API, which the tracker instruments automatically: each goto() and link navigation records a pageview with transition timing. No afterNavigate hook required.
Events from components
<script>
function onSignupClick() {
window.webanalytics?.track('cta_clicked', {
cta: 'signup',
page: 'home',
});
}
</script>
<button on:click={onSignupClick}>Start free</button>For SSR safety in shared utilities, guard with the browser flag:
import { browser } from '$app/environment';
export function track(name, props) {
if (browser) window.webanalytics?.track(name, props);
}Identity and server-side revenue
// After login, in the browser
window.webanalytics?.identify(user.email);
// Persist the visitor id (e.g. via a form action or fetch)
await fetch('/api/me', {
method: 'PATCH',
body: JSON.stringify({
clycyo_visitor_id: window.webanalytics?.getVisitorId(),
}),
});With the ID stored, +server.ts endpoints handling billing webhooks can post revenue events that join to the visitor's first-touch UTM — the full attribution chain with two extra lines.
What arrives automatically
- Pageviews (initial + client navigations) with per-visit load time.
- Field Web Vitals — where SvelteKit usually shines, and now you can prove it with real-user LCP and INP instead of lab claims.
- JS errors with the route, clicks, referrers, UTM and device context.
Prerendered marketing pages, SSR app routes, static adapter output — the tag behaves identically across all of them. Start on the free tier and check your Vitals victory lap in the dashboard.