diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/.gitignore b/dev-packages/e2e-tests/test-applications/svelte-5-static/.gitignore
new file mode 100644
index 000000000000..a547bf36d8d1
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/README.md b/dev-packages/e2e-tests/test-applications/svelte-5-static/README.md
new file mode 100644
index 000000000000..89a8fa13539e
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/README.md
@@ -0,0 +1,62 @@
+# Svelte + TS + Vite
+
+This template should help get you started developing with Svelte and TypeScript in Vite.
+
+## Recommended IDE Setup
+
+[VS Code](https://code.visualstudio.com/) +
+[Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
+
+## Need an official Svelte framework?
+
+Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its
+serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less,
+and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
+
+## Technical considerations
+
+**Why use this over SvelteKit?**
+
+- It brings its own routing solution which might not be preferable for some users.
+- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
+
+This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account
+the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other
+`create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
+
+Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been
+structured similarly to SvelteKit so that it is easy to migrate.
+
+**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
+
+Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash
+references keeps the default TypeScript setting of accepting type information from the entire workspace, while also
+adding `svelte` and `vite/client` type information.
+
+**Why include `.vscode/extensions.json`?**
+
+Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to
+install the recommended extension upon opening the project.
+
+**Why enable `allowJs` in the TS template?**
+
+While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of
+JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds:
+not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing
+JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant.
+
+**Why is HMR not preserving my local component state?**
+
+HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and
+`@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details
+[here](https://github.com/rixo/svelte-hmr#svelte-hmr).
+
+If you have state that's important to retain within a component, consider creating an external store which would not be
+replaced by HMR.
+
+```ts
+// store.ts
+// An extremely simple external store
+import { writable } from 'svelte/store';
+export default writable(0);
+```
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/index.html b/dev-packages/e2e-tests/test-applications/svelte-5-static/index.html
new file mode 100644
index 000000000000..b6c5f0afafd6
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite + Svelte + TS
+
+
+
+
+
+
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/package.json b/dev-packages/e2e-tests/test-applications/svelte-5-static/package.json
new file mode 100644
index 000000000000..9a508ab13017
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "svelte-5-static",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "check": "svelte-check --tsconfig ./tsconfig.json",
+ "test:prod": "TEST_ENV=production playwright test",
+ "test:build": "pnpm install && pnpm build",
+ "test:assert": "pnpm test:prod"
+ },
+ "devDependencies": {
+ "@playwright/test": "~1.56.0",
+ "@sentry-internal/test-utils": "link:../../../test-utils",
+ "@sveltejs/vite-plugin-svelte": "^3.0.2",
+ "@tsconfig/svelte": "^5.0.2",
+ "svelte": "^5.0.0-next.115",
+ "svelte-check": "^3.6.7",
+ "tslib": "^2.6.2",
+ "typescript": "^5.2.2",
+ "vite": "^5.4.11"
+ },
+ "dependencies": {
+ "@sentry/svelte": "file:../../packed/sentry-svelte-packed.tgz"
+ },
+ "volta": {
+ "extends": "../../package.json"
+ }
+}
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/playwright.config.mjs b/dev-packages/e2e-tests/test-applications/svelte-5-static/playwright.config.mjs
new file mode 100644
index 000000000000..0c468af7d879
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/playwright.config.mjs
@@ -0,0 +1,8 @@
+import { getPlaywrightConfig } from '@sentry-internal/test-utils';
+
+const config = getPlaywrightConfig({
+ startCommand: 'pnpm preview --port 3030',
+ port: 3030,
+});
+
+export default config;
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/public/vite.svg b/dev-packages/e2e-tests/test-applications/svelte-5-static/public/vite.svg
new file mode 100644
index 000000000000..e7b8dfb1b2a6
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/src/App.svelte b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/App.svelte
new file mode 100644
index 000000000000..47d6be1385b4
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/App.svelte
@@ -0,0 +1,52 @@
+
+
+
+
+ Vite + Svelte
+
+
+
+ throwError()}>Error
+
+
+
+ Check out SvelteKit , the official Svelte app framework powered by Vite!
+
+
+
+ Click on the Vite and Svelte logos to learn more
+
+
+
+
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/src/app.css b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/app.css
new file mode 100644
index 000000000000..617f5e93c0a7
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/app.css
@@ -0,0 +1,79 @@
+:root {
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+.card {
+ padding: 2em;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/src/assets/svelte.svg b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/assets/svelte.svg
new file mode 100644
index 000000000000..c5e08481f8ae
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/assets/svelte.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/src/lib/Counter.svelte b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/lib/Counter.svelte
new file mode 100644
index 000000000000..397bfd1c7321
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/lib/Counter.svelte
@@ -0,0 +1,17 @@
+
+
+
+ count is {count}
+
+
+
+ doubled: {doubled}
+
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/src/main.ts b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/main.ts
new file mode 100644
index 000000000000..5a475cb7ab95
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/main.ts
@@ -0,0 +1,25 @@
+import { mount } from 'svelte';
+import App from './App.svelte';
+import './app.css';
+
+import * as Sentry from '@sentry/svelte';
+
+Sentry.init({
+ traceLifecycle: 'static',
+ environment: 'qa', // dynamic sampling bias to keep transactions
+ dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
+ tracesSampleRate: 1.0,
+ integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()],
+ tunnel: 'http://localhost:3031/', // proxy server
+ debug: !!process.env.DEBUG,
+});
+
+const target = document.getElementById('app');
+
+if (!target) {
+ throw new Error('Could not find target element');
+}
+
+const app = mount(App, { target });
+
+export default app;
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/src/vite-env.d.ts b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/vite-env.d.ts
new file mode 100644
index 000000000000..4078e7476a2e
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/src/vite-env.d.ts
@@ -0,0 +1,2 @@
+///
+///
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/svelte-5-static/start-event-proxy.mjs
new file mode 100644
index 000000000000..185667e2a854
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/start-event-proxy.mjs
@@ -0,0 +1,6 @@
+import { startEventProxyServer } from '@sentry-internal/test-utils';
+
+startEventProxyServer({
+ port: 3031,
+ proxyServerName: 'svelte-5-static',
+});
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/svelte.config.js b/dev-packages/e2e-tests/test-applications/svelte-5-static/svelte.config.js
new file mode 100644
index 000000000000..15884bc6346a
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/svelte.config.js
@@ -0,0 +1,14 @@
+import { withSentryConfig } from '@sentry/svelte';
+import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
+
+const config = {
+ // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
+ // for more information about preprocessors
+ preprocess: vitePreprocess(),
+};
+
+const configWithSentry = withSentryConfig(config, {
+ componentTracking: { trackComponents: true, trackInit: true },
+});
+
+export default configWithSentry;
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/svelte-5-static/tests/errors.test.ts
new file mode 100644
index 000000000000..34e4920d0cf9
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/tests/errors.test.ts
@@ -0,0 +1,30 @@
+import { expect, test } from '@playwright/test';
+import { waitForError } from '@sentry-internal/test-utils';
+
+test('sends an error', async ({ page }) => {
+ const errorPromise = waitForError('svelte-5-static', async errorEvent => {
+ return !errorEvent.type;
+ });
+
+ await page.goto(`/`);
+
+ await page.locator('#errorBtn').click();
+
+ const error = await errorPromise;
+
+ expect(error).toMatchObject({
+ exception: {
+ values: [
+ {
+ type: 'Error',
+ value: 'Error thrown from Svelte 5 E2E test app',
+ mechanism: {
+ type: 'auto.browser.browserapierrors.addEventListener',
+ handled: false,
+ },
+ },
+ ],
+ },
+ transaction: '/',
+ });
+});
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/tests/performance.test.ts b/dev-packages/e2e-tests/test-applications/svelte-5-static/tests/performance.test.ts
similarity index 92%
rename from dev-packages/e2e-tests/test-applications/svelte-5/tests/performance.test.ts
rename to dev-packages/e2e-tests/test-applications/svelte-5-static/tests/performance.test.ts
index e3623b62eb47..7ffd622648b0 100644
--- a/dev-packages/e2e-tests/test-applications/svelte-5/tests/performance.test.ts
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/tests/performance.test.ts
@@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
test('sends a pageload transaction with component tracking init spans', async ({ page }) => {
- const transactionPromise = waitForTransaction('svelte-5', async transactionEvent => {
+ const transactionPromise = waitForTransaction('svelte-5-static', async transactionEvent => {
return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload';
});
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/tsconfig.json b/dev-packages/e2e-tests/test-applications/svelte-5-static/tsconfig.json
new file mode 100644
index 000000000000..5fb548f2b4f6
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/svelte/tsconfig.json",
+ "compilerOptions": {
+ "target": "ESNext",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "resolveJsonModule": true,
+ /**
+ * Typecheck JS in `.svelte` and `.js` files by default.
+ * Disable checkJs if you'd like to use dynamic types in JS.
+ * Note that setting allowJs false does not prevent the use
+ * of JS in `.svelte` files.
+ */
+ "allowJs": true,
+ "checkJs": true,
+ "isolatedModules": true
+ },
+ "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/tsconfig.node.json b/dev-packages/e2e-tests/test-applications/svelte-5-static/tsconfig.node.json
new file mode 100644
index 000000000000..d02c37dfe5fd
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "strict": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5-static/vite.config.ts b/dev-packages/e2e-tests/test-applications/svelte-5-static/vite.config.ts
new file mode 100644
index 000000000000..73f8ad0c1a43
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5-static/vite.config.ts
@@ -0,0 +1,8 @@
+import { svelte } from '@sveltejs/vite-plugin-svelte';
+import { defineConfig } from 'vite';
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [svelte()],
+ envPrefix: 'PUBLIC_',
+});
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts b/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts
index 5a475cb7ab95..9f5fb70cea94 100644
--- a/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts
+++ b/dev-packages/e2e-tests/test-applications/svelte-5/src/main.ts
@@ -5,7 +5,6 @@ import './app.css';
import * as Sentry from '@sentry/svelte';
Sentry.init({
- traceLifecycle: 'static',
environment: 'qa', // dynamic sampling bias to keep transactions
dsn: import.meta.env.PUBLIC_E2E_TEST_DSN,
tracesSampleRate: 1.0,
diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/tests/spans.test.ts b/dev-packages/e2e-tests/test-applications/svelte-5/tests/spans.test.ts
new file mode 100644
index 000000000000..45d1fae25167
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/svelte-5/tests/spans.test.ts
@@ -0,0 +1,40 @@
+import { expect, test } from '@playwright/test';
+import { collectStreamedSpans, getSpanOp } from '@sentry-internal/test-utils';
+
+test('sends a pageload span with component tracking init spans', async ({ page }) => {
+ const spansPromise = collectStreamedSpans('svelte-5', spansOfTrace =>
+ spansOfTrace.some(span => getSpanOp(span) === 'pageload' && span.is_segment),
+ );
+
+ await page.goto(`/`);
+
+ const spans = await spansPromise;
+ const pageloadSpan = spans.find(span => getSpanOp(span) === 'pageload' && span.is_segment);
+
+ expect(pageloadSpan?.name).toBe('Pageload');
+ expect(pageloadSpan?.attributes).toMatchObject({
+ 'sentry.op': { value: 'pageload', type: 'string' },
+ 'sentry.origin': { value: 'auto.pageload.browser', type: 'string' },
+ 'sentry.segment.name.source': { value: 'url', type: 'string' },
+ 'url.path': { value: '/', type: 'string' },
+ });
+
+ expect(spans).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ name: '',
+ attributes: expect.objectContaining({
+ 'sentry.op': { value: 'ui.mount', type: 'string' },
+ 'sentry.origin': { value: 'auto.ui.svelte', type: 'string' },
+ }),
+ }),
+ expect.objectContaining({
+ name: '',
+ attributes: expect.objectContaining({
+ 'sentry.op': { value: 'ui.mount', type: 'string' },
+ 'sentry.origin': { value: 'auto.ui.svelte', type: 'string' },
+ }),
+ }),
+ ]),
+ );
+});