From ca97e5aad739d8071e754b2e8c073be8ebcc1917 Mon Sep 17 00:00:00 2001 From: Muspi Merol Date: Sat, 3 Oct 2026 05:36:19 +0800 Subject: [PATCH 1/4] fix(sveltekit): replace removed $app/stores with $app/state for SvelteKit 3 --- packages/web/package.json | 4 ++-- packages/web/src/sveltekit/index.ts | 24 ++++++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/web/package.json b/packages/web/package.json index c820d94..3cf8bff 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -123,7 +123,7 @@ }, "peerDependencies": { "@remix-run/react": "^2", - "@sveltejs/kit": "^1 || ^2", + "@sveltejs/kit": "^2.12 || ^3", "next": ">= 13", "nuxt": ">= 3", "react": "^18 || ^19 || ^19.0.0-rc", @@ -157,4 +157,4 @@ "optional": true } } -} +} \ No newline at end of file diff --git a/packages/web/src/sveltekit/index.ts b/packages/web/src/sveltekit/index.ts index 6ff3193..df22585 100644 --- a/packages/web/src/sveltekit/index.ts +++ b/packages/web/src/sveltekit/index.ts @@ -1,6 +1,6 @@ import type {} from '@sveltejs/kit'; import { browser } from '$app/environment'; -import { page } from '$app/stores'; +import { page } from '$app/state'; import { inject, pageview, track } from '../generic'; import type { AnalyticsProps, BeforeSend, BeforeSendEvent } from '../types'; import { getBasePath, getConfigString } from './utils'; @@ -17,11 +17,23 @@ function injectAnalytics(props: Omit = {}): void { getConfigString(), ); - page.subscribe(({ route, url }) => { - if (route?.id) { - pageview({ route: route.id, path: url.pathname }); - } - }); + // $app/stores was removed in SvelteKit 3; use $app/state's reactive `page` + History API + const trackPageview = () => { + const route = page.route.id; + if (route) pageview({ route, path: page.url.pathname }); + }; + + trackPageview(); + + for (const type of ['pushState', 'replaceState'] as const) { + const original = history[type]; + history[type] = function (...args: Parameters) { + original.apply(this, args); + trackPageview(); + }; + } + + window.addEventListener('popstate', trackPageview); } } From 1d44fca68598c3eaa2a7b27fbfae1a2747d65ab0 Mon Sep 17 00:00:00 2001 From: Muspi Merol Date: Tue, 6 Oct 2026 11:45:04 +0800 Subject: [PATCH 2/4] fix(sveltekit): restore package.json trailing newline --- packages/web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/package.json b/packages/web/package.json index 3cf8bff..1d8b8be 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -157,4 +157,4 @@ "optional": true } } -} \ No newline at end of file +} From d9421e4553bc69e60feeffffcef966078faa60f0 Mon Sep 17 00:00:00 2001 From: Muspi Merol Date: Tue, 6 Oct 2026 13:35:03 +0800 Subject: [PATCH 3/4] chore: update lockfile for sveltekit peer range --- pnpm-lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3935034..2e6e786 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -221,7 +221,7 @@ importers: specifier: ^2 version: 2.17.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) '@sveltejs/kit': - specifier: ^1 || ^2 + specifier: ^2.12 || ^3 version: 2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@22.19.19)(esbuild@0.24.2)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@8.0.13(@types/node@22.19.19)(esbuild@0.24.2)(jiti@2.7.0)(terser@5.47.1)(yaml@2.9.0)) next: specifier: '>= 13' From 0e27c0327c00067def375deb17807e5b1d04911d Mon Sep 17 00:00:00 2001 From: Muspi Merol Date: Tue, 6 Oct 2026 20:46:50 +0800 Subject: [PATCH 4/4] fix(sveltekit): track page views after navigation --- apps/sveltekit/README.md | 2 +- .../src/routes/{+layout.ts => +layout.svelte} | 4 +++ packages/web/src/sveltekit/index.ts | 25 +++++-------------- 3 files changed, 11 insertions(+), 20 deletions(-) rename apps/sveltekit/src/routes/{+layout.ts => +layout.svelte} (88%) diff --git a/apps/sveltekit/README.md b/apps/sveltekit/README.md index 2fc0b88..6ebf889 100644 --- a/apps/sveltekit/README.md +++ b/apps/sveltekit/README.md @@ -7,7 +7,7 @@ This application was created with the following commands: - `cd apps` - `pnpx sv create sveltekit` (answers: SvelteKit minimal, no Typescript, no additional install, pnpm) - `cd sveltekit` -- add `src/+layout.js` to include `import { injectAnalytics } from '@vercel/analytics/sveltekit'; injectAnalytics();` +- add `src/routes/+layout.svelte` to include `import { injectAnalytics } from '@vercel/analytics/sveltekit'; injectAnalytics();` - edit package.json to add `"@vercel/analytics": "workspace:*"` dependency and change `@sveltejs/adapter-auto` into `@sveltejs/adapter-vercel` - eddi `svelte.config.js` to change `@sveltejs/adapter-auto` into `@sveltejs/adapter-vercel` - `pnpm i` diff --git a/apps/sveltekit/src/routes/+layout.ts b/apps/sveltekit/src/routes/+layout.svelte similarity index 88% rename from apps/sveltekit/src/routes/+layout.ts rename to apps/sveltekit/src/routes/+layout.svelte index 0275424..2855ee5 100644 --- a/apps/sveltekit/src/routes/+layout.ts +++ b/apps/sveltekit/src/routes/+layout.svelte @@ -1,3 +1,4 @@ + + + diff --git a/packages/web/src/sveltekit/index.ts b/packages/web/src/sveltekit/index.ts index df22585..d5fc60b 100644 --- a/packages/web/src/sveltekit/index.ts +++ b/packages/web/src/sveltekit/index.ts @@ -1,6 +1,6 @@ import type {} from '@sveltejs/kit'; import { browser } from '$app/environment'; -import { page } from '$app/state'; +import { afterNavigate } from '$app/navigation'; import { inject, pageview, track } from '../generic'; import type { AnalyticsProps, BeforeSend, BeforeSendEvent } from '../types'; import { getBasePath, getConfigString } from './utils'; @@ -17,25 +17,12 @@ function injectAnalytics(props: Omit = {}): void { getConfigString(), ); - // $app/stores was removed in SvelteKit 3; use $app/state's reactive `page` + History API - const trackPageview = () => { - const route = page.route.id; - if (route) pageview({ route, path: page.url.pathname }); - }; - - trackPageview(); - - for (const type of ['pushState', 'replaceState'] as const) { - const original = history[type]; - history[type] = function (...args: Parameters) { - original.apply(this, args); - trackPageview(); - }; - } - - window.addEventListener('popstate', trackPageview); + // SvelteKit owns registration and cleanup; callers must invoke this from component initialization. + afterNavigate(({ to }) => { + if (to?.route.id) pageview({ route: to.route.id, path: to.url.pathname }); + }); } } -export { injectAnalytics, track }; export type { AnalyticsProps, BeforeSend, BeforeSendEvent }; +export { injectAnalytics, track };