Frameworks · 2 min setup
How to add analytics to SvelteKit
<head> of src/app.html, above %sveltekit.head%. Every page is rendered from that template, and SvelteKit's client-side navigations are counted as pageviews automatically.Updated
src/app.html is the HTML shell SvelteKit fills for every route — server-rendered, prerendered or SPA-mode. A tag there is present once on every page and is never re-inserted when the router swaps page content, which is exactly what an analytics script needs.
SvelteKit at a glance
- Where the tag goes
src/app.html, inside<head>- Route changes
- Tracked automatically (
goto, links, back/forward) - CSP
- Add
visitrack.apptokit.cspdirectives - Adapters
- Works with every adapter (Vercel, Netlify, Node, static, Cloudflare)
- Custom events
window.visitrack()in the browser
How to install VisitTrack on SvelteKit
Step 1: Copy your site id
Copy your snippet from the VisitTrack install step or Settings → General.
SITE_IDbelow is the placeholder.Step 2: Add the tag to src/app.html
Place it in
<head>, before%sveltekit.head%.src/app.html<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <script defer data-site="SITE_ID" src="https://visitrack.app/tracker.js"></script> %sveltekit.head% </head> <body data-sveltekit-preload-data="hover"> <div style="display: contents">%sveltekit.body%</div> </body> </html>Step 3: If you use kit.csp, allow visitrack.app
SvelteKit can generate a Content-Security-Policy for you. Add the VisitTrack origin to
script-src(the script) andconnect-src(where it sends events).svelte.config.jsconst config = { kit: { csp: { directives: { "script-src": ["self", "https://visitrack.app"], "connect-src": ["self", "https://visitrack.app"], }, }, }, }; export default config;Step 4: Build, deploy and browse
vite devruns on localhost, which is ignored. Deploy and click around the live site.
How to check VisitTrack is working on SvelteKit
- Open the deployed site, then navigate between two routes.
- VisitTrack's live view shows you within seconds; the Pages tab lists both routes.
- DevTools → Network: one
POSTtovisitrack.app/api/collectper navigation.
Does VisitTrack track SvelteKit page navigation?
SvelteKit's client router updates the URL with history.pushState (and replaceState for goto(url, { replaceState: true })). The tracker wraps both and listens for popstate, so links, goto() and back/forward are pageviews. Pageviews are keyed on the pathname, so updating only search params (?q=… in a search box) isn't counted again.
Link preloading (data-sveltekit-preload-data) fetches data on hover but doesn't change the URL, so it never creates a pageview.
How to track custom events and goals in SvelteKit
Call window.visitrack() in browser code — an event handler, onMount, or after a form action resolves with enhance. Use optional chaining, since server rendering has no window and a blocker may stop the script.
<script lang="ts">
import { enhance } from "$app/forms";
</script>
<form method="POST" action="?/signup" use:enhance={() => {
return async ({ result, update }) => {
if (result.type === "success") window.visitrack?.("signup", { method: "email" });
await update();
};
}}>
<input name="email" type="email" required />
<button>Create account</button>
</form>Plain clicks only need data-vt-goal="cta_click" on the element. With automatic events on (the default), any form submit also records a form_submit event named after the form's id, name or action.
Script options you might need on SvelteKit
All optional — add them to the same tag. Full reference: script configuration.
| Attribute | What it does |
|---|---|
data-cookieless | Store nothing in the browser; the server derives a daily-rotating id. See cookieless mode. |
data-exclude="/app/*" | Never track these paths (comma-separated, * wildcard). Checked on every navigation. |
data-allow-local | Track on localhost and *.local — for testing an install only. |
data-debug | Log every event the script sends, and why it skipped one, to the console. |
data-auto="false" | Turn off automatic events (downloads, contact clicks, form submits, rage clicks, JS errors, 404s). |
SvelteKit troubleshooting
Refused to load the script in the console
Your kit.csp (or a header from your host) doesn't allow the origin. Add it to script-src and connect-src as above.
window is not defined
A call ran during SSR. Use it inside onMount or an event handler, or guard with import { browser } from "$app/environment".
No data while developing
Expected — localhost is skipped. Add data-allow-local temporarily to test, and remove it before deploying.
Prerendered pages don't show the tag
Check you edited src/app.html (not a layout's <svelte:head>) and rebuilt. Every prerendered page is generated from app.html.
SvelteKit analytics FAQ
Should I use svelte:head or app.html for the VisitTrack tag?
Use app.html. It's rendered once for every route, while <svelte:head> in a layout is managed per component and is easier to end up with in two places. The tracker should be loaded exactly once.
Does VisitTrack track SvelteKit client-side navigation?
Yes. The script hooks the History API that SvelteKit's router uses, so every route change is recorded. You don't need an afterNavigate callback.
Does it work with adapter-static and SPA mode?
Yes. The tag lives in the generated HTML shell, and navigation is tracked in the browser either way.
Can I track form actions as conversions?
Yes — call window.visitrack("signup") in the enhance callback when result.type === "success", then make that event a goal in Settings → Goals.
Is VisitTrack GDPR-friendly for a SvelteKit site?
Its cookieless mode stores nothing on the device and never stores IP addresses, so it's designed to run without a consent banner. Mention VisitTrack in your privacy policy. General information, not legal advice.
Keep going
- Astro analyticsAdd VisitTrack to Astro with one is:inline tag in your shared layout — works for static, SSR and ClientRouter (view transitions) sites.
- Next.js analyticsAdd VisitTrack to a Next.js App Router or Pages Router app with next/script — client-side route changes are tracked automatically.
- Vue analyticsAdd VisitTrack to a Vue 3 app built with Vite by adding one tag to index.html — Vue Router history-mode navigations are tracked automatically.
- Cloudflare Pages analyticsAdd VisitTrack on Cloudflare Pages in your HTML or with an HTMLRewriter middleware, exclude it from Rocket Loader, and track AI crawlers at the edge.
- Install the tracking scriptThe reference tag, CSP notes and how to check it's working.
- Custom events and signupsvisitrack(), data-vt-goal, scroll events and server-side signups.
- Use casesHow SaaS teams, indie hackers, stores and agencies use VisitTrack.
- VisitTrack vs Google AnalyticsCookie-free analytics with revenue attribution, compared honestly.
Add VisitTrack to your SvelteKit site
Cookie-free analytics with revenue attribution, live visitors, funnels and session replays. One script tag, every feature on every plan. 14 days free, no card required.
Not on SvelteKit? See all 29 integration guides.