npx skills add ...
npx skills add getsentry/agent-skills --skill sentry-svelte-sdk
npx skills add getsentry/agent-skills --skill sentry-svelte-sdk
Full Sentry SDK setup for Svelte and SvelteKit. Use when asked to "add Sentry to Svelte", "add Sentry to SvelteKit", "install @sentry/sveltekit", or configure error monitoring, tracing, session replay, or logging for Svelte or SvelteKit applications.
The same skill content is published under more than one repo. The install counts are split across them; any of these commands works.
Opinionated wizard that scans your project and guides you through complete Sentry setup for Svelte and SvelteKit.
@sentry/svelte, @sentry/sveltekit, or Sentry SDK for SvelteNote: SDK versions and APIs below reflect current Sentry docs at time of writing (
@sentry/sveltekit≥10.8.0, SvelteKit ≥2.31.0). Always verify against docs.sentry.io/platforms/javascript/guides/sveltekit/ before implementing.
Run these commands to understand the project before making any recommendations:
What to determine:
| Question | Impact |
|---|---|
@sveltejs/kit in package.json? | SvelteKit path vs. plain Svelte path |
| SvelteKit ≥2.31.0? | Modern (instrumentation.server.ts) vs. legacy setup |
@sentry/sveltekit already present? | Skip install, go straight to feature config |
vite.config.ts present? | Source map upload via Vite plugin available |
| Backend directory found? | Trigger Phase 4 cross-link suggestion |
Present a concrete recommendation based on what you found. Don't ask open-ended questions — lead with a proposal:
Recommended (core coverage):
Optional (enhanced observability):
Sentry.logger.*; recommend when app uses server-side logging or needs log-to-trace correlationRecommendation logic:
| Feature | Recommend when... |
|---|---|
| Error Monitoring | Always — non-negotiable baseline |
| Tracing | Always for SvelteKit (client + server); for plain Svelte when calling APIs |
| Session Replay | User-facing app, login flows, or checkout pages present |
| Logging | App already uses server-side logging, or structured log search is needed |
Propose: "I recommend setting up Error Monitoring + Tracing + Session Replay. Want me to also add structured Logging?"
| Your project | Package | Setup complexity |
|---|---|---|
| SvelteKit (≥2.31.0) | @sentry/sveltekit | 5 files to create/modify |
| SvelteKit (<2.31.0) | @sentry/sveltekit | 3 files (init in hooks.server.ts) |
Plain Svelte (no @sveltejs/kit) | @sentry/svelte | Single entry point |
The wizard walks you through login, org/project selection, and auth token setup interactively — no manual token creation needed. It then installs the SDK, creates all necessary files (client/server hooks, Vite plugin config), configures source map upload, and adds a /sentry-example-page for verification. Skip to Verification after running it.
Step 1 — Install
Step 2 — svelte.config.js — Enable instrumentation
Step 3 — src/instrumentation.server.ts — Server-side init (runs once at startup)
Step 4 — src/hooks.client.ts — Client-side init
Step 5 — src/hooks.server.ts — Server hooks (no init here in modern setup)
Step 6 — vite.config.ts — Source maps (requires SENTRY_AUTH_TOKEN)
Add to .env (never commit):
@sentry/sveltekit <10.8.0)Skip instrumentation.server.ts and svelte.config.js changes. Instead, put Sentry.init() directly in hooks.server.ts:
hooks.client.ts and vite.config.ts are identical to the modern path.
Install:
Configure in entry point (src/main.ts or src/main.js) before mounting the app:
Optional: Svelte component tracking (auto-injects tracking into all components):
Walk through features one at a time. Load the reference file, follow its steps, then verify before moving on:
| Feature | Reference | Load when... |
|---|---|---|
| Error Monitoring | ${SKILL_ROOT}/references/error-monitoring.md | Always (baseline) |
| Tracing | ${SKILL_ROOT}/references/tracing.md | API calls / distributed tracing needed |
| Session Replay | ${SKILL_ROOT}/references/session-replay.md | User-facing app |
| Logging | ${SKILL_ROOT}/references/logging.md | Structured logs / log-to-trace correlation |
For each feature: Read ${SKILL_ROOT}/references/<feature>.md, follow steps exactly, verify it works.
| File | Purpose | Modern | Legacy |
|---|---|---|---|
src/instrumentation.server.ts | Server Sentry.init() — runs once at startup | ✅ Required | ❌ |
src/hooks.client.ts | Client Sentry.init() + handleError | ✅ Required | ✅ Required |
src/hooks.server.ts | handleError + sentryHandle() (no init) | ✅ Required | ✅ Init goes here |
svelte.config.js | Enable experimental.instrumentation.server | ✅ Required | ❌ |
vite.config.ts | sentrySvelteKit() plugin for source maps | ✅ Recommended | ✅ Recommended |
.env | SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT | ✅ For source maps | ✅ For source maps |
Sentry.init() Options| Option | Type | Default | Notes |
|---|---|---|---|
dsn | string | — | Required. Use env var; SDK is disabled when empty |
environment | string | "production" | e.g., "staging", "development" |
release | string | — | e.g., "my-app@1.2.3" or git SHA |
sendDefaultPii | boolean | false | Includes IP addresses and request headers |
tracesSampleRate | number | — | 0–1; use 1.0 in dev, 0.1–0.2 in prod |
tracesSampler | function | — | Per-transaction sampling; overrides tracesSampleRate |
tracePropagationTargets | (string|RegExp)[] | — | URLs that receive distributed tracing headers |
replaysSessionSampleRate | number | — | Fraction of all sessions recorded (client only) |
replaysOnErrorSampleRate | number | — | Fraction of error sessions recorded (client only) |
enableLogs | boolean | false | Enable Sentry.logger.* API |
beforeSendLog | function | — | Filter/modify logs before send |
debug | boolean | false | Verbose SDK output to console |
instrumentation.server.ts / hooks.server.ts)| Option | Type | Notes |
|---|---|---|
serverName | string | Hostname tag on server events |
includeLocalVariables | boolean | Attach local vars to stack frames |
shutdownTimeout | number | ms to flush events before process exit (default: 2000) |
| Adapter | Support |
|---|---|
@sveltejs/adapter-auto / adapter-vercel (Node) | ✅ Full |
@sveltejs/adapter-node | ✅ Full |
@sveltejs/adapter-cloudflare | ⚠️ Partial — requires extra setup |
| Vercel Edge Runtime | ❌ Not supported |
After setup, trigger test events to confirm Sentry is receiving data:
Check the Sentry dashboard:
If nothing appears, set debug: true in Sentry.init() and check the browser/server console for SDK output.
After completing Svelte/SvelteKit setup, check for a companion backend missing Sentry coverage:
If a backend exists without Sentry configured, suggest the matching skill:
| Backend detected | Suggest skill |
|---|---|
Go (go.mod) | sentry-go-sdk |
Python (requirements.txt, pyproject.toml) | sentry-python-sdk |
Ruby (Gemfile) | sentry-ruby-sdk |
| Node.js (Express, Fastify, etc.) | Use @sentry/node — see docs.sentry.io/platforms/javascript/guides/express/ |
| Issue | Solution |
|---|---|
| Events not appearing | Set debug: true, check DSN, open browser console for SDK errors |
| Source maps not working | Run npm run build (not dev), verify SENTRY_AUTH_TOKEN is set |
| Server errors not captured | Ensure handleErrorWithSentry() is exported from hooks.server.ts |
| Client errors not captured | Ensure handleErrorWithSentry() is exported from hooks.client.ts |
| Session replay not recording | Confirm replayIntegration() is in client init only (never server) |
sentryHandle() + other handles not composing | Wrap with sequence(Sentry.sentryHandle(), myHandle) |
| Ad-blocker blocking events | Set tunnel: "/sentry-tunnel" and add a server-side relay endpoint |
| SvelteKit instrumentation not activating | Confirm experimental.instrumentation.server: true in svelte.config.js |
| Cloudflare adapter issues | Consult docs.sentry.io/platforms/javascript/guides/sveltekit/ for adapter-specific notes |
wrapLoadWithSentry / wrapServerLoadWithSentry errors | These are legacy wrappers — remove them; sentryHandle() instruments load functions automatically in ≥10.8.0 |
npx @sentry/wizard@latest -i sveltekitnpm install @sentry/sveltekit --saveimport adapter from "@sveltejs/adapter-auto";
const config = {
kit: {
adapter: adapter(),
experimental: {
instrumentation: { server: true },
tracing: { server: true },
},
},
};
export default config;import * as Sentry from "@sentry/sveltekit";
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.SENTRY_ENVIRONMENT,
release: process.env.SENTRY_RELEASE,
sendDefaultPii: true,
tracesSampleRate: 1.0, // lower to 0.1–0.2 in production
enableLogs: true,
});import * as Sentry from "@sentry/sveltekit";
Sentry.init({
dsn: import.meta.env.PUBLIC_SENTRY_DSN ?? import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
sendDefaultPii: true,
tracesSampleRate: 1.0,
integrations: [
Sentry.replayIntegration({
maskAllText: true,
blockAllMedia: true,
}),
],
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
enableLogs: true,
});
export const handleError = Sentry.handleErrorWithSentry();import * as Sentry from "@sentry/sveltekit";
import { sequence } from "@sveltejs/kit/hooks";
export const handleError = Sentry.handleErrorWithSentry();
// sentryHandle() instruments incoming requests and creates root spans
export const handle = Sentry.sentryHandle();
// If you have other handle functions, compose with sequence():
// export const handle = sequence(Sentry.sentryHandle(), myAuthHandle);import { sveltekit } from "@sveltejs/kit/vite";
import { sentrySvelteKit } from "@sentry/sveltekit";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [
// sentrySvelteKit MUST come before sveltekit()
sentrySvelteKit({
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
sveltekit(),
],
});SENTRY_AUTH_TOKEN=sntrys_...
SENTRY_ORG=my-org-slug
SENTRY_PROJECT=my-project-slug// src/hooks.server.ts (legacy — init goes here)
import * as Sentry from "@sentry/sveltekit";
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
enableLogs: true,
});
export const handleError = Sentry.handleErrorWithSentry();
export const handle = Sentry.sentryHandle();npm install @sentry/svelte --saveimport * as Sentry from "@sentry/svelte";
import App from "./App.svelte";
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
sendDefaultPii: true,
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration({
maskAllText: true,
blockAllMedia: true,
}),
],
tracesSampleRate: 1.0,
tracePropagationTargets: ["localhost", /^https:\/\/yourapi\.io/],
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
enableLogs: true,
});
const app = new App({ target: document.getElementById("app")! });
export default app;// svelte.config.js
import { withSentryConfig } from "@sentry/svelte";
export default withSentryConfig(
{ compilerOptions: {} },
{ componentTracking: { trackComponents: true } }
);<!-- src/routes/sentry-test/+page.svelte -->
<script>
import * as Sentry from "@sentry/sveltekit";
</script>
<button onclick={() => { throw new Error("Sentry client test"); }}>
Test Client Error
</button>
<button onclick={() => Sentry.captureMessage("Sentry test message", "info")}>
Test Message
</button>// src/routes/sentry-test/+server.ts
export const GET = () => {
throw new Error("Sentry server test");
};# Look for backend in adjacent directories
ls ../backend ../server ../api ../go ../python 2>/dev/null
cat ../go.mod 2>/dev/null | head -3
cat ../requirements.txt ../pyproject.toml 2>/dev/null | head -3
cat ../Gemfile 2>/dev/null | head -3