Quick start
By the end of this guide, the Flare client is running in your Svelte app: it reports errors with the component that threw and its parent chain, shows your real source code in stack traces instead of minified code, and traces your page loads, navigations, and component mounts.
Looking for the V1 docs of the JavaScript SDK? You can find them here.
Install and start the client
You need a Flare account and a project key, which you can find on your project's settings page. Flare's Svelte integration requires Svelte 5.3 or newer and uses two packages: @flareapp/js, the core client that catches errors and sends them to Flare, and one integration package on top, depending on your setup:
- Plain Svelte (no SvelteKit):
@flareapp/svelte. - SvelteKit (2.12 or newer):
@flareapp/sveltekitinstead. It depends on@flareapp/svelteand re-exports everything from it, so you only add the one package, not both.
The rest of this guide shows both. Pick the one that matches your project.
The interactive guide below is the fastest way to get started. It fills in your real project key for you when you are logged in, and gives you copy-paste commands to install the package and start the client. Or you can let an AI agent do all the work for you by using the install prompt. It covers plain Svelte projects; if you're using SvelteKit, follow the hooks.client.ts steps below instead.
This guide covers every supported setup. Follow only the steps that match your project: conditional instructions start with a bold "If ..." line describing when they apply. Steps without such a line always apply. Install commands use
npm install. Useyarn addinstead if the project uses Yarn. ReplacePROJECT PUBLIC KEYwith the project's public key. You can find it in the project settings on https://flareapp.io.
Step 1: Install the package using NPM or Yarn
If you don't upload sourcemaps to Flare:
npm install @flareapp/js @flareapp/svelte
If you use Vite and upload sourcemaps to Flare:
npm install @flareapp/js @flareapp/svelte @flareapp/vite
If you use Webpack and upload sourcemaps to Flare:
npm install @flareapp/js @flareapp/svelte @flareapp/webpack
If you use Next.js and upload sourcemaps to Flare:
npm install @flareapp/js @flareapp/svelte @flareapp/nextjs
Step 2: Register Flare & configure
Initialize Flare in your main.ts file:
If you use Vite and upload sourcemaps to Flare:
In main.ts:
import { mount } from "svelte";
import { flare } from "@flareapp/js";
import App from "./App.svelte";
// Only enable Flare in production, we don't want to waste your quota while you're developing:
if (import.meta.env.PROD) {
flare.light();
}
mount(App, { target: document.querySelector("#app")! });
If you use Webpack or Next.js and upload sourcemaps to Flare:
In main.ts:
import { mount } from "svelte";
import { flare } from "@flareapp/js";
import App from "./App.svelte";
// Only enable Flare in production, we don't want to waste your quota while you're developing:
if (process.env.NODE_ENV === 'production') {
flare.light();
}
mount(App, { target: document.querySelector("#app")! });
If you use Vite without uploading sourcemaps to Flare:
In main.ts:
import { mount } from "svelte";
import { flare } from "@flareapp/js";
import App from "./App.svelte";
// Only enable Flare in production, we don't want to waste your quota while you're developing:
if (import.meta.env.PROD) {
flare.light('PROJECT PUBLIC KEY');
}
mount(App, { target: document.querySelector("#app")! });
If you don't use Vite and don't upload sourcemaps to Flare:
In main.ts:
import { mount } from "svelte";
import { flare } from "@flareapp/js";
import App from "./App.svelte";
// Only enable Flare in production, we don't want to waste your quota while you're developing:
if (process.env.NODE_ENV === 'production') {
flare.light('PROJECT PUBLIC KEY');
}
mount(App, { target: document.querySelector("#app")! });
Wrap your app with the Flare error boundary to catch and report component errors. In your root App.svelte:
In App.svelte:
<script lang="ts">
import { FlareErrorBoundary } from '@flareapp/svelte';
import Root from './Root.svelte';
</script>
<FlareErrorBoundary>
<Root />
{#snippet failed(error, reset)}
<p>{error.message}</p>
<button onclick={reset}>Try again</button>
{/snippet}
</FlareErrorBoundary>
To get the full component hierarchy in error reports, wrap your Svelte config with withFlareConfig in svelte.config.js:
In svelte.config.js:
import { withFlareConfig } from '@flareapp/svelte/config';
export default withFlareConfig({
// your existing config
});
If you use Vite and upload sourcemaps to Flare:
Configure Vite to upload sourcemaps to Flare:
In vite.config.js:
import { defineConfig } from 'vite';
import flareSourcemaps from '@flareapp/vite';
export default defineConfig({
plugins: [
flareSourcemaps({
apiKey: 'PROJECT PUBLIC KEY'
}),
],
});
If you use Webpack and upload sourcemaps to Flare:
Configure Webpack to upload sourcemaps to Flare:
In webpack.config.js:
const { FlareWebpackPlugin } = require("@flareapp/webpack");
module.exports = {
// ...
devtool: "source-map",
plugins: [ new FlareWebpackPlugin({ apiKey: "PROJECT PUBLIC KEY" }) ],
};
If you use Next.js and upload sourcemaps to Flare:
Wrap your Next.js config with withFlareSourcemaps in next.config.mjs:
In next.config.mjs:
import { withFlareSourcemaps } from '@flareapp/nextjs';
export default withFlareSourcemaps({
// your normal Next.js config
}, {
apiKey: 'PROJECT PUBLIC KEY',
});
Step 3: Connect your project key
If you upload sourcemaps to Flare:
When you install Flare's sourcemap build plugin, the build plugin injects your public key so flare.light() can run without an explicit key. Make sure you add the domains of your application in the project settings on Flare.
If you don't upload sourcemaps to Flare:
Pass your public key directly to flare.light('PROJECT PUBLIC KEY') and make sure you add the domains of your application in the project settings on Flare.
Step 4: Verify your setup
Add this code temporarily to verify everything is working:
In app.js:
flare.test();
If you use Vite and upload sourcemaps to Flare:
Run your Vite build command. You should see the following lines in the output:
@flareapp/vite: Uploading xx sourcemap(s) to Flare.
@flareapp/vite: Successfully uploaded all sourcemaps to Flare.
If you use Next.js and upload sourcemaps to Flare:
Run next build. You should see the following lines in the output:
@flareapp/webpack: Uploading 4 sourcemap(s) to Flare.
@flareapp/webpack: Successfully uploaded all sourcemaps to Flare.
Prefer to install and configure the client by hand, or not logged in? Install the package:
npm install @flareapp/js @flareapp/svelte
yarn add @flareapp/js @flareapp/svelte
pnpm add @flareapp/js @flareapp/svelte
Using SvelteKit? Install @flareapp/sveltekit instead of @flareapp/svelte:
npm install @flareapp/js @flareapp/sveltekit
yarn add @flareapp/js @flareapp/sveltekit
pnpm add @flareapp/js @flareapp/sveltekit
In plain Svelte, add this near the top of your application's entry file, before any other code runs, so the client can catch errors as early as possible:
import { flare } from '@flareapp/js';
if (import.meta.env.PROD) {
flare.light('YOUR PROJECT KEY');
}
In SvelteKit, put the same call in src/hooks.client.ts instead. That file runs before any route or layout code, which makes it the earliest place a SvelteKit app can start the client:
// src/hooks.client.ts
import { flare } from '@flareapp/js';
if (import.meta.env.PROD) {
flare.light('YOUR PROJECT KEY');
}
The guard keeps the client off during local development, so you don't use up your quota while you work.
flare.light() switches on the client's automatic error listeners. From that point on, unhandled errors and unhandled promise rejections are caught and sent to Flare on their own, without any extra code from you.
Catch errors with the boundary
flare.light() catches errors outside of Svelte's rendering, but a rendering error, for example a component that throws while it renders, needs its own catch. Wrap your component tree in FlareErrorBoundary, which wraps Svelte's native <svelte:boundary>.
In plain Svelte, wrap the root component you mount, for example in src/App.svelte:
<!-- src/App.svelte -->
<script>
import { FlareErrorBoundary } from '@flareapp/svelte';
import Root from './Root.svelte';
</script>
<FlareErrorBoundary>
<Root />
</FlareErrorBoundary>
In SvelteKit, wrap {@render children()} in your root layout, src/routes/+layout.svelte. Import FlareErrorBoundary from @flareapp/sveltekit instead; it is re-exported from @flareapp/svelte:
<!-- src/routes/+layout.svelte -->
<script>
import { FlareErrorBoundary } from '@flareapp/sveltekit';
let { children } = $props();
</script>
<FlareErrorBoundary>
{@render children()}
</FlareErrorBoundary>
This catches errors during rendering below it and reports them to Flare with the component name, the component hierarchy, and the error origin. Read more in error boundary, including how to show a fallback UI and reset the boundary on navigation.
If you're using SvelteKit, also set up handleErrorWithFlare() in src/hooks.client.ts. It catches errors that never reach a component boundary at all, for example ones thrown from a load function:
// src/hooks.client.ts
import { handleErrorWithFlare } from '@flareapp/sveltekit/client';
export const handleError = handleErrorWithFlare();
See SvelteKit error handling for what this hook reports and how to add server-side error handling too.
Check that errors arrive
Add a component that throws while it renders, so the FlareErrorBoundary you just added actually catches it. A <svelte:boundary> only catches errors from rendering and effects; an error thrown from an event handler or a setTimeout callback would not be caught, so make sure your test error throws directly in the component body:
<script>
throw new Error('My first Flare error');
</script>
Render this component somewhere inside your FlareErrorBoundary, then open your project in Flare. The error shows up within a few seconds, with its message, a stack trace, the component that threw, and the browser it came from. Remove the test component once you have confirmed it arrived.
See your real source code
If you bundle your code for production, the stack trace above points at minified, bundled output instead of the file and line you actually wrote. Fix that by uploading a sourcemap after every build, using the Vite or Webpack plugin. The Svelte integration uses the same plugins as the core JavaScript client. Follow see your real source code in the JavaScript quick start for the install and config steps, then come back here.
Turn on tracing
You've now got error reporting working. The remaining steps add tracing and component profiling. You can stop here and come back to them later; nothing below is required to get errors into Flare.
Tracing shows you where time goes during a page load, a client side navigation, and the requests your page makes. Turn it on with flare.configure():
import { flare } from '@flareapp/js';
flare.configure({
enableTracing: true,
tracesSampleRate: 1,
});
enableTracing defaults to false, so tracing is off until you set it. tracesSampleRate controls what fraction of traces gets sent, from 0 to 1, and defaults to 1, meaning every trace is sent. Lower it once you have real traffic, so you don't ship a trace for every single page load.
Once tracing is on, the browser client automatically traces page loads, client side navigations, and the fetch or XMLHttpRequest calls your page makes. This part does not need SvelteKit: even plain Svelte gets a browser_navigation span whenever the path changes through the History API. Without SvelteKit, that span has no route pattern, because there is no router to read one from. It only knows the raw path. The next step adds route patterns for SvelteKit apps, and the one after that adds component mount spans.
Read more in how tracing works and what gets traced.
Trace navigations
You can stop here and come back later; nothing below is required to get errors into Flare.
This step is SvelteKit only. Plain Svelte has no router for Flare to read route patterns from.
In src/hooks.client.ts, call traceSvelteKitRouter(). Unlike a router integration in other frameworks, it takes no arguments: it reads SvelteKit's own navigation state directly, through $app/state.
// src/hooks.client.ts
import { flare } from '@flareapp/js';
import { handleErrorWithFlare, traceSvelteKitRouter } from '@flareapp/sveltekit/client';
flare.light('YOUR PROJECT KEY');
export const handleError = handleErrorWithFlare();
traceSvelteKitRouter();
Once called, browser_navigation and browser_pageload spans also contain the matched SvelteKit route, for example /products/[id], next to the raw path.

Read more in tracing introduction for Svelte.
Profile components
You can stop here and come back later; nothing below is required to get errors into Flare.
Component profiling in Svelte is different from every other framework Flare supports: it happens at build time, through a preprocessor, so the setup lives in svelte.config.js, not in your application code. List the components you want to time as the profileComponents option to withFlareConfig:
// svelte.config.js
import { withFlareConfig } from '@flareapp/svelte/config';
export default withFlareConfig({
// your existing svelte config
}, {
profileComponents: ['ProductPage', 'ProductGallery'],
});
Because this is a build time setting, changing profileComponents needs a restart of your dev server before it takes effect. This only records mounts, not re-renders, and it needs enableTracing on, which you already set in the tracing step above.
Read more in profiling introduction for Svelte, including how component names inside
src/routesare matched.
Common problems
See common problems in the JavaScript quick start for problems that apply to every JavaScript app, such as the client never being started or a wrong project key. Below are two that are specific to Svelte.
profileComponents in svelte.config.js looks like it does nothing. This option lives in svelte.config.js, not on a plugin call in your application code. If you add it and don't see any change, check that you restarted your dev server after saving the file: the preprocessor only reads the config when the build starts, so an already running dev server keeps using the old setting.
A route file like +page.svelte doesn't match its bare name in profileComponents. Every route in a SvelteKit app can have a file named +page.svelte, so matching route files by bare name would make every route collide under one name. Flare matches those by the file's path under src/routes instead, for example products/[id]/+page, not +page, except at the root of src/routes itself and inside a route group, which stay +page and (marketing)/about/+page respectively. See profiling introduction for Svelte for the full explanation.
Next steps
- Error boundary and error handler: fallback UI, resetting on navigation, and using your own
<svelte:boundary>. - SvelteKit error handling: the
handleErrorWithFlare()hook, route context, and reporting errors manually. - Reporting errors: report caught errors and send log messages by hand.
- Client hooks: change or drop a report before it's sent.
- Sourcemaps: sourcemaps for Vite, Webpack, Next.js, Laravel Mix, and manual uploads.
- Adding custom context and identifying users.
- Tracing introduction for Svelte, plus sampling and manual spans.
- Profiling introduction for Svelte.
- API reference and configuration reference.