SvelteKit's full-stack architecture — server components, API routes, client-side hydration — gives you flexibility, but also means errors can hide in two different runtimes. A crashed API endpoint, a broken server-side component, or a client-side render error can each go unnoticed unless you're capturing them all. This guide sets up production-grade sveltekit error tracking using the Sentry SDK pointed at LightTrace, so full-stack failures surface immediately with the context you need to fix them.
By the end you'll capture server-side errors, client-side errors, API route failures, and unhandled promise rejections — all with stack traces mapped back to your source.
Install and initialize the Sentry SDK
Start by adding the Sentry SDK to your project. Because LightTrace is Sentry-SDK-compatible, you use the standard @sentry/sveltekit package and change only the dsn.
npm install @sentry/sveltekit
Create or update your src/hooks.server.js to initialize Sentry on the server. This runs once at startup and installs global handlers for uncaught exceptions:
// src/hooks.server.js
import * as Sentry from "@sentry/sveltekit";
Sentry.init({
dsn: "https://<key>@your-lighttrace-host/1",
environment: process.env.NODE_ENV,
release: `web@${process.env.npm_package_version}`,
tracesSampleRate: 1.0,
});
export const handle = Sentry.sentryHandle();
This single snippet installs middleware that catches server errors and sends them to LightTrace. Paired with an export const handleError hook, you can customize how errors are reported before they leave the server.
Capture server-side errors with handleError
SvelteKit's handleError hook runs whenever an error bubbles up in a route, component, or API handler. Combine it with Sentry to report the error and add context:
// src/hooks.server.js
export async function handleError({ error, event }) {
const errorId = crypto.randomUUID();
Sentry.captureException(error, {
contexts: {
sveltekit: {
route: event.route.id,
method: event.request.method,
url: event.url.pathname,
},
},
});
return {
message: "An unexpected error occurred",
errorId,
};
}
Now every server error — a database query that failed, a missing environment variable, a logic bug — arrives in your LightTrace dashboard with the route, HTTP method, and URL. The errorId you return can be shown to users so they can report it if needed.
Wrap database calls and external API requests in try-catch to add custom context before they bubble up. This makes traces richer and faster to debug.
Capture client-side errors and promise rejections
Server errors are only half the story. Client-side JavaScript errors — component render errors, event handler crashes, failed fetches — need capturing too. Create src/hooks.client.js to initialize Sentry on the browser:
// src/hooks.client.js
import * as Sentry from "@sentry/sveltekit";
Sentry.init({
dsn: "https://<key>@your-lighttrace-host/1",
environment: import.meta.env.MODE,
release: `web@${import.meta.env.VITE_APP_VERSION}`,
tracesSampleRate: 1.0,
});
export const handle = Sentry.sentryHandle();
The browser SDK automatically captures uncaught errors and unhandled promise rejections, so from this point forward any client-side crash is reported. If you want to handle errors differently on the client — for example, to show a custom toast instead of a blank page — add a client-side error handler:
// src/hooks.client.js
export async function handleError({ error, event }) {
Sentry.captureException(error);
// Show user-friendly message without exposing stack trace
console.error("Client error:", error);
return {
message: "Something went wrong",
};
}
The client-side handleError hook runs for errors thrown during SvelteKit's server-side rendering (hydration) and during client-side navigation. Both paths send errors to Sentry, so you catch the full spectrum.
Upload source maps for readable stack traces
In production your JavaScript is minified, so a raw stack trace points at index-4f9a.js:1:52210 — useless. Source maps map that back to your real .ts or .js files. Configure your Vite build to generate source maps:
// vite.config.ts
import { defineConfig } from 'vite'
import { sveltekit } from '@sveltejs/kit/vite'
export default defineConfig({
plugins: [sveltekit()],
build: {
sourcemap: true,
},
});
Then upload the maps to LightTrace in your CI pipeline as part of your deploy. Our source maps guide walks through the exact pipeline; the same idea applies whether you're building with Vite or another bundler. Without source maps, your traces point at minified code; with them, they point to the exact line you wrote.
Add context to speed up debugging
Raw errors are a starting point. The real speed-up comes from context — who hit the error, what they did, and which release introduced it. Set the user and add breadcrumbs at meaningful moments:
// After user login
Sentry.setUser({ id: user.id, email: user.email });
// Before key operations
Sentry.addBreadcrumb({
category: "checkout",
message: "User clicked place order",
level: "info",
});
// On important state changes
Sentry.addBreadcrumb({
category: "state",
message: "Cart updated",
data: { itemCount: cart.length },
});
Now every error arrives with the breadcrumb trail that led to it — the exact clicks, API calls, and state changes that triggered the crash. This cuts debugging time from hours to minutes because you can reproduce the failure instead of guessing the path.
Trace API route errors
SvelteKit API routes are regular Node.js code running on the server, so they're captured by the handleError hook. But you can go deeper: wrap your route handlers to capture the request and response:
// src/routes/api/checkout/+server.ts
import * as Sentry from "@sentry/sveltekit";
export async function POST({ request }) {
return Sentry.wrapServerRouteWithSentry(async () => {
const body = await request.json();
if (!body.cartId) {
throw new Error("Missing cartId");
}
const result = await processPayment(body.cartId);
return new Response(JSON.stringify(result), { status: 200 });
});
}
This wrapper attaches request details — the URL, method, and any custom data — so when an API route crashes, you see exactly what the client sent and what the server was doing.
Never log sensitive data like API keys, passwords, or payment tokens in breadcrumbs or error context. If you must include structured data, use data scrubbing rules in your LightTrace project settings to redact PII before storage.
What you've set up
You now have production-grade error tracking across your entire SvelteKit app:
- Server errors — uncaught exceptions, failed database queries, and API route crashes surface with route and request context.
- Client errors — render crashes, event handler exceptions, and unhandled promise rejections are captured with breadcrumbs.
- Source-mapped traces — every stack frame points back to your original
.tsor.sveltefiles, not minified code. - User context — you know who hit the error, when, and what they did beforehand.
The pattern is the same as adding error tracking to any app — initialize once, let global handlers catch the rest, and add context where it matters. SvelteKit's handleError hooks make this especially clean because the framework gives you a single point to intercept and enrich all failures.
Start tracking errors in minutes
Capture your first SvelteKit error and see it grouped in minutes — point the Sentry SDK at LightTrace and start your free trial today.
Full-stack error tracking isn't a nice-to-have you bolt on after launch. It's how you ship SvelteKit apps with confidence, knowing that the next production bug becomes an actionable issue instead of a frustrated user report.