Skip to content
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
67ca823
initial boilerplate
Lms24 Aug 27, 2025
566a928
test expectation
Lms24 Aug 27, 2025
2f2e29d
ast mod progress
Lms24 Aug 28, 2025
b44cc54
add working and tested svelte config modification
Lms24 Aug 28, 2025
9344e8c
add instrumentation.server.ts code insertion
Lms24 Aug 28, 2025
0637e38
various improvements
Lms24 Aug 28, 2025
ac52ccd
conditionally inject init into server
Lms24 Aug 28, 2025
f000a06
.
Lms24 Aug 28, 2025
4b4eab6
template tests
Lms24 Aug 28, 2025
f71d712
make kit.config.experimental.tracing depend on tracing selection
Lms24 Aug 28, 2025
fd4e505
changelog
Lms24 Aug 28, 2025
74724ed
add e2e test with clifty
Lms24 Aug 28, 2025
e0ac63b
add tests
Lms24 Aug 28, 2025
e071cf6
finalize e2e test
Lms24 Aug 28, 2025
d914ce3
add missing file
Lms24 Aug 28, 2025
c9bc10f
add e2e test to CI
Lms24 Aug 28, 2025
2eb8a4b
fix changelog
Lms24 Aug 28, 2025
768783d
for real
Lms24 Aug 28, 2025
886d289
fix timeout in CI?
Lms24 Aug 28, 2025
0a92e46
expect installation output
Lms24 Aug 28, 2025
a9e24a7
dynamic test args in snapshots
Lms24 Aug 28, 2025
4e8f01c
changelog
Lms24 Aug 28, 2025
ef5c34b
I hate AI
Lms24 Aug 28, 2025
4333a27
rename other sveltekit e2e test app to avoid ambiguity in CI
Lms24 Aug 28, 2025
0893b94
remove debug flag
Lms24 Aug 28, 2025
8bea3e4
one more rename
Lms24 Aug 28, 2025
2862039
nope 2 more renames
Lms24 Aug 28, 2025
e923fee
additional tests
Lms24 Sep 1, 2025
70592e2
unskip macos tests
Lms24 Sep 1, 2025
35bc982
Update src/sveltekit/sdk-setup/setup.ts
Lms24 Sep 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ jobs:
- NextJS-15
- Remix
- React-Native
- Sveltekit
- Sveltekit-Hooks
- Sveltekit-Tracing
- Help
- Cloudflare-Wrangler-Sourcemaps
os:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

- feat(sveltekit): Add support for SDK setup with `instrumentation.server.ts` ([#1077](https://github.com/getsentry/sentry-wizard/pull/1077))

This release adds support for setting up the SvelteKit SDK in SvelteKit versions 2.31.0 or higher.

## 6.3.0

- feat(nextjs,remix,sveltekit,react-native,flutter,ios,angular,android,nuxt): add support to add MCP server during wizard based installlations ([#1063](https://github.com/getsentry/sentry-wizard/pull/1063))
Expand Down
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to rename the sveltekit test app to sveltekit-hooks to avoid ambiguity with sveltekit-tracing.

File renamed without changes.
21 changes: 21 additions & 0 deletions e2e-tests/test-applications/sveltekit-tracing-test-app/.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-*
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "sveltekit-test-app",
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
"@sveltejs/adapter-node": "^5.3.1",
"@sveltejs/kit": "2.31.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "^5.0.0",
"vite": "^5.0.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// See https://svelte.dev/docs/kit/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}

export {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const handle = async ({ event, resolve }) => {
const response = await resolve(event);
return response;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// place files you want to import through the `$lib` alias in this folder.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://svelte.dev/docs/kit/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),

kit: {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter(),
experimental: {
remoteFunctions: true,
},
},
};

export default config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"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://svelte.dev/docs/kit/configuration#alias
// except $lib which is handled by https://svelte.dev/docs/kit/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
}
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()]
});
235 changes: 235 additions & 0 deletions e2e-tests/tests/sveltekit-tracing.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
import * as path from 'node:path';
import * as fs from 'node:fs';
import { Integration } from '../../lib/Constants';
import {
checkEnvBuildPlugin,
checkFileExists,
checkIfBuilds,
checkIfRunsOnDevMode,
checkIfRunsOnProdMode,
checkPackageJson,
cleanupGit,
getWizardCommand,
initGit,
revertLocalChanges,
TEST_ARGS,
} from '../utils';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

//@ts-expect-error - clifty is ESM only
import { KEYS, withEnv } from 'clifty';

describe('Sveltekit with instrumentation and tracing', () => {
describe('without existing files', () => {
const projectDir = path.resolve(
__dirname,
'../test-applications/sveltekit-tracing-test-app',
);

const integration = Integration.sveltekit;
let wizardExitCode: number;

beforeAll(async () => {
initGit(projectDir);
revertLocalChanges(projectDir);

wizardExitCode = await withEnv({
cwd: projectDir,
})
.defineInteraction()
.expectOutput(
'The Sentry SvelteKit Wizard will help you set up Sentry for your application',
)
.step('package installation', ({ expectOutput, whenAsked }) => {
whenAsked('Please select your package manager.').respondWith(
KEYS.DOWN,
KEYS.ENTER,
);
expectOutput('Installing @sentry/sveltekit');
})
.step('SDK setup', ({ whenAsked }) => {
whenAsked('Do you want to enable Tracing', {
timeout: 90_000, // package installation can take a while in CI
}).respondWith(KEYS.ENTER);
whenAsked('Do you want to enable Session Replay').respondWith(
KEYS.ENTER,
);
whenAsked('Do you want to enable Logs').respondWith(KEYS.ENTER);
})
.whenAsked('Do you want to create an example page')
.respondWith(KEYS.ENTER)
.whenAsked(
'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',
)
.respondWith(KEYS.DOWN, KEYS.ENTER)
.expectOutput('Successfully installed the Sentry SvelteKit SDK!')
.run(getWizardCommand(integration));
});

afterAll(() => {
revertLocalChanges(projectDir);
cleanupGit(projectDir);
});

it('exits with exit code 0', () => {
expect(wizardExitCode).toBe(0);
});

it('adds the SDK dependency to package.json', () => {
checkPackageJson(projectDir, integration);
});

it('adds the .env.sentry-build-plugin', () => {
checkEnvBuildPlugin(projectDir);
});

it('adds the example page', () => {
checkFileExists(
path.resolve(projectDir, 'src/routes/sentry-example-page/+page.svelte'),
);
checkFileExists(
path.resolve(projectDir, 'src/routes/sentry-example-page/+server.js'),
);
});

it('adds the sentry plugin to vite.config.ts', () => {
const viteConfig = fs.readFileSync(
path.resolve(projectDir, 'vite.config.ts'),
);
expect(viteConfig.toString()).toMatchInlineSnapshot(`
"import { sentrySvelteKit } from "@sentry/sveltekit";
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
plugins: [sentrySvelteKit({
sourceMapsUploadOptions: {
org: "${TEST_ARGS.ORG_SLUG}",
project: "${TEST_ARGS.PROJECT_SLUG}"
}
}), sveltekit()]
});"
`);
});

it('creates the hook files', () => {
const clientHooks = fs.readFileSync(
path.resolve(projectDir, 'src/hooks.client.ts'),
);
const serverHooks = fs.readFileSync(
path.resolve(projectDir, 'src/hooks.server.ts'),
);

expect(clientHooks.toString()).toMatchInlineSnapshot(`
"import { handleErrorWithSentry, replayIntegration } from "@sentry/sveltekit";
import * as Sentry from '@sentry/sveltekit';

Sentry.init({
dsn: '${TEST_ARGS.PROJECT_DSN}',

tracesSampleRate: 1.0,

// Enable logs to be sent to Sentry
enableLogs: true,

// This sets the sample rate to be 10%. You may want this to be 100% while
// in development and sample at a lower rate in production
replaysSessionSampleRate: 0.1,

// If the entire session is not sampled, use the below sample rate to sample
// sessions when an error occurs.
replaysOnErrorSampleRate: 1.0,

// If you don't want to use Session Replay, just remove the line below:
integrations: [replayIntegration()],
});

// If you have a custom error handler, pass it to \`handleErrorWithSentry\`
export const handleError = handleErrorWithSentry();
"
`);

expect(serverHooks.toString()).toMatchInlineSnapshot(`
"import {sequence} from "@sveltejs/kit/hooks";
import * as Sentry from "@sentry/sveltekit";
export const handle = sequence(Sentry.sentryHandle(), async ({ event, resolve }) => {
const response = await resolve(event);
return response;
});
export const handleError = Sentry.handleErrorWithSentry();"
`);
});

it('creates the insturmentation.server file', () => {
const instrumentationServer = fs.readFileSync(
path.resolve(projectDir, 'src/instrumentation.server.ts'),
);

expect(instrumentationServer.toString()).toMatchInlineSnapshot(`
"import * as Sentry from '@sentry/sveltekit';

Sentry.init({
dsn: '${TEST_ARGS.PROJECT_DSN}',

tracesSampleRate: 1.0,

// Enable logs to be sent to Sentry
enableLogs: true,

// uncomment the line below to enable Spotlight (https://spotlightjs.com)
// spotlight: import.meta.env.DEV,
});"
`);
});

it('enables tracing and instrumentation in svelte.config.js', () => {
const svelteConfig = fs.readFileSync(
path.resolve(projectDir, 'svelte.config.js'),
);
expect(svelteConfig.toString()).toMatchInlineSnapshot(`
"import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://svelte.dev/docs/kit/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),

kit: {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter(),
experimental: {
remoteFunctions: true,

tracing: {
server: true,
},

instrumentation: {
server: true,
},
},
},
};

export default config;"
`);
});

// checkSvelteKitProject(projectDir, integration);
it('builds successfully', async () => {
await checkIfBuilds(projectDir);
});

it('runs on dev mode correctly', async () => {
await checkIfRunsOnDevMode(projectDir, 'ready in');
});

it('runs on prod mode correctly', async () => {
await checkIfRunsOnProdMode(projectDir, 'to expose', 'preview');
});
});
});
Loading
Loading