Skip to content

Commit

Permalink
feat: sveltekit route support
Browse files Browse the repository at this point in the history
  • Loading branch information
feugy committed Nov 5, 2024
1 parent 524af71 commit 7721408
Show file tree
Hide file tree
Showing 17 changed files with 2,948 additions and 1,253 deletions.
21 changes: 21 additions & 0 deletions apps/sveltekit/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
node_modules

# Output
.output
.vercel
/.svelte-kit
/build

# OS
.DS_Store
Thumbs.db

# Env
.env
.env.*
!.env.example
!.env.test

# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
1 change: 1 addition & 0 deletions apps/sveltekit/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
17 changes: 17 additions & 0 deletions apps/sveltekit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Sveltekit Demo application for Vercel Web Analytics

## Setup

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 { injectWebAnalytics } from '@vercel/analytics/sveltekit'; injectWebAnalytics();`
- 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`

## Usage

Start it with `cd apps/sveltekit` + `pnpm dev` and browse to [http://localhost:5173](http://localhost:5173)
18 changes: 18 additions & 0 deletions apps/sveltekit/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}
23 changes: 23 additions & 0 deletions apps/sveltekit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "sveltekit",
"version": "0.0.1",
"private": true,
"type": "module",
"scripts": {
"build": "vite build",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
"dev": "vite dev",
"prepare": "svelte-kit sync",
"preview": "vite preview"
},
"devDependencies": {
"@sveltejs/adapter-vercel": "latest",
"@sveltejs/kit": "latest",
"@sveltejs/vite-plugin-svelte": "latest",
"@vercel/analytics": "workspace:*",
"svelte": "latest",
"svelte-check": "latest",
"typescript": "latest",
"vite": "latest"
}
}
12 changes: 12 additions & 0 deletions apps/sveltekit/src/app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!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" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
3 changes: 3 additions & 0 deletions apps/sveltekit/src/routes/+layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { injectWebAnalytics } from '@vercel/analytics/sveltekit';

injectWebAnalytics();
2 changes: 2 additions & 0 deletions apps/sveltekit/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="/bruno">this page</a> to know more...</p>
10 changes: 10 additions & 0 deletions apps/sveltekit/src/routes/[slug]/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script>
import { page } from '$app/stores';
import { track } from '@vercel/analytics/sveltekit';
</script>

<h1>We don't talk about {$page.params.slug}</h1>

<a href="/" onclick={() => track('go-back', { slug: $page.params.slug })}
>Go back</a
>
Binary file added apps/sveltekit/static/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions apps/sveltekit/svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import adapter from '@sveltejs/adapter-vercel';

/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: { adapter: adapter() },
};

export default config;
6 changes: 6 additions & 0 deletions apps/sveltekit/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
plugins: [sveltekit()],
});
25 changes: 18 additions & 7 deletions packages/web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vercel/analytics",
"version": "1.3.2",
"version": "1.4.0",
"description": "Gain real-time traffic insights with Vercel Web Analytics",
"keywords": [
"analytics",
Expand Down Expand Up @@ -34,6 +34,10 @@
"import": "./dist/server/index.mjs",
"require": "./dist/server/index.js",
"default": "./dist/server/index.js"
},
"./sveltekit": {
"svelte": "./dist/sveltekit/index.mjs",
"types": "./dist/sveltekit/index.d.ts"
}
},
"main": "./dist/index.mjs",
Expand All @@ -51,6 +55,9 @@
],
"next": [
"dist/next/index.d.ts"
],
"sveltekit": [
"dist/sveltekit/index.d.ts"
]
}
},
Expand All @@ -77,26 +84,30 @@
"server-only": "^0.0.1"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@swc/core": "^1.3.66",
"@swc/jest": "^0.2.26",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@types/jest": "^29.5.2",
"@testing-library/jest-dom": "^6.2.0",
"@testing-library/react": "^14.1.2",
"@types/node": "^20.3.1",
"@types/react": "^18.2.14",
"@types/testing-library__jest-dom": "^5.14.6",
"@vercel/eslint-config": "workspace:0.0.0",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"svelte": "^5",
"tsup": "7.1.0"
},
"peerDependencies": {
"@sveltejs/kit": "^1 || ^2",
"next": ">= 13",
"react": "^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@sveltejs/kit": {
"optional": true
},
"next": {
"optional": true
},
Expand Down
14 changes: 11 additions & 3 deletions packages/web/src/generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ function inject(
} = {
debug: true,
}
): void {
if (!isBrowser()) return;
): { setRoute: (route: string) => void } | null {
if (!isBrowser()) return null;

setMode(props.mode);

Expand All @@ -48,7 +48,12 @@ function inject(
const src =
props.scriptSrc || (isDevelopment() ? DEV_SCRIPT_URL : PROD_SCRIPT_URL);

if (document.head.querySelector(`script[src*="${src}"]`)) return;
if (document.head.querySelector(`script[src*="${src}"]`)) return null;

function setRoute(route?: string | null): void {
console.log('>>setRoute', route);
script.dataset.route = route ?? undefined;
}

const script = document.createElement('script');
script.src = src;
Expand All @@ -66,6 +71,7 @@ function inject(
if (props.dsn) {
script.dataset.dsn = props.dsn;
}
setRoute(props.route);

script.onerror = (): void => {
const errorMessage = isDevelopment()
Expand All @@ -83,6 +89,8 @@ function inject(
}

document.head.appendChild(script);

return { setRoute };
}

/**
Expand Down
30 changes: 30 additions & 0 deletions packages/web/src/sveltekit/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { get } from 'svelte/store';
import { inject, track, type AnalyticsProps } from '../generic';
import { page } from '$app/stores';
import { browser } from '$app/environment';
import type {} from '@sveltejs/kit'; // don't remove, ensures ambient types for $app/* are loaded

function injectWebAnalytics(
props: Omit<AnalyticsProps, 'framework'> = {}
): void {
if (browser) {
const webAnalytics = inject({
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- route could be undefined in layout.js file
route: get(page).route?.id,
...props,
framework: 'sveltekit',
});

if (webAnalytics) {
page.subscribe((value) => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- route could be undefined in layout.js file
if (value.route?.id) {
webAnalytics.setRoute(value.route.id);
}
});
}
}
}

export { injectWebAnalytics, track };
export type { AnalyticsProps };
8 changes: 8 additions & 0 deletions packages/web/tsup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,12 @@ export default defineConfig([
},
outDir: 'dist/server',
},
{
...cfg,
entry: {
index: 'src/sveltekit/index.ts',
},
external: ['svelte', '@sveltejs/kit', '$app'],
outDir: 'dist/sveltekit',
},
]);
Loading

0 comments on commit 7721408

Please sign in to comment.