Flare by Spatie
    • Error Tracking
    • Performance Monitoring
    • Logs Coming soon
  • Pricing
  • Docs
  • Insights
  • Changelog
  • Back to Flare ⌘↵ Shortcut: Command or Control Enter
  • Sign in
  • Try Flare for free
  • Error Tracking
  • Performance Monitoring
  • Logs Coming soon
  • Pricing
  • Docs
  • Insights
  • Changelog
    • Back to Flare ⌘↵ Shortcut: Command or Control Enter
    • Try Flare for free
    • Sign in
Flare Flare Laravel Laravel PHP PHP JavaScript JavaScript React React Vue Vue Svelte Svelte Protocol Protocol
  • General
  • Installation
  • Resolving bundled code
  • API reference
  • Errors
  • Error boundary
  • Error handler
  • SvelteKit error handling
  • Reporting errors
  • Client hooks
  • Data Collection
  • Adding custom context
  • Adding glows

Error boundary

The FlareErrorBoundary component wraps Svelte's native <svelte:boundary> to catch errors during rendering and report them to Flare with Svelte-specific context including the component name, component hierarchy, and error origin.

Basic usage

Wrap your component tree (or parts of it) in the FlareErrorBoundary:

<script>
    import { FlareErrorBoundary } from '@flareapp/svelte';
</script>

<FlareErrorBoundary>
    <MyComponent />
</FlareErrorBoundary>

Without a failed snippet, the boundary renders nothing when an error is caught.

Displaying a fallback UI

Use the failed snippet to render a fallback when an error is caught. The snippet receives the caught error and a reset function to clear the error state:

<script>
    import { FlareErrorBoundary } from '@flareapp/svelte';
</script>

<FlareErrorBoundary>
    <App />
    {#snippet failed(error, reset)}
        <div>
            <h2>Something went wrong</h2>
            <p>{error.message}</p>
            <button onclick={reset}>Try again</button>
        </div>
    {/snippet}
</FlareErrorBoundary>

Resetting the error boundary

You can automatically reset the error boundary when certain values change using the resetKeys prop. When any value in the array changes between renders (compared per-index via Object.is), the boundary automatically resets and re-renders its children.

A common use case is resetting the boundary when the user navigates to a different page:

<script>
    import { page } from '$app/state';
    import { FlareErrorBoundary } from '@flareapp/svelte';

    let { children } = $props();
</script>

<FlareErrorBoundary
    resetKeys={[page.url.pathname]}
    onReset={(error) => {
        console.log('Navigated away from error, previous error:', error?.message);
    }}
>
    {@render children()}
    {#snippet failed(error, reset)}
        <p>Something went wrong.</p>
    {/snippet}
</FlareErrorBoundary>

The onReset callback fires when the error boundary resets (either via reset() from the failed snippet or via resetKeys changing). It receives the previous error, allowing conditional cleanup.

Lifecycle hooks

The error boundary provides three hooks that fire at different stages of the error reporting lifecycle. The beforeSubmit and afterSubmit callbacks receive a context object with the following shape:

{
    svelte: {
        componentName: string | null;
        componentHierarchy: string[];
        errorOrigin: 'render' | 'event' | 'effect' | 'unknown';
    }
}

Both types are exported from @flareapp/svelte as FlareSvelteContext and SvelteErrorOrigin.

The callbacks are not wrapped in a try/catch. If a hook throws, the boundary itself will crash, so keep the logic defensive.

beforeEvaluate

Fires before the component hierarchy context is built. This is the place to attach custom context, tags, or user information to the Flare report:

<script>
    import { flare } from '@flareapp/js';
    import { FlareErrorBoundary } from '@flareapp/svelte';
</script>

<FlareErrorBoundary
    beforeEvaluate={({ error }) => {
        flare.addContext('user', { id: currentUser.id });
        flare.addContext('feature-flags', getActiveFlags());
    }}
>
    <App />
</FlareErrorBoundary>

beforeSubmit

Fires after the component hierarchy context is built but before the error is reported to Flare. The callback receives the context and must return a (possibly modified) context object. Use this to filter or enrich the report context:

<FlareErrorBoundary
    beforeSubmit={({ error, context }) => {
        return {
            ...context,
            svelte: {
                ...context.svelte,
                componentHierarchy: context.svelte.componentHierarchy.filter(
                    (name) => name !== 'ThirdPartyWrapper',
                ),
            },
        };
    }}
>
    <App />
</FlareErrorBoundary>

afterSubmit

Fires after flare.report() is called. Note that the report is sent asynchronously, so this callback runs after the report is initiated, not after the network request completes. Use this for side effects like logging to a secondary service, showing a toast, or updating app state:

<FlareErrorBoundary
    afterSubmit={({ error, context }) => {
        console.error('Caught by FlareErrorBoundary:', error);
        console.error('Reported context:', context);
    }}
>
    <App />
</FlareErrorBoundary>

Filtering errors

The error boundary hooks above are designed for adding context and running side effects; they cannot prevent an error from being reported. To filter or suppress errors, use the core JavaScript client hooks via flare.configure().

Note that the boundary's beforeEvaluate and beforeSubmit are different hooks from flare.configure({ beforeEvaluate, beforeSubmit }) — they share the same name but have different signatures and capabilities. The execution order when both are configured is:

  1. Boundary beforeEvaluate (adds context, cannot suppress)
  2. flare.report() is called internally, which triggers:
  3. Client beforeEvaluate via flare.configure() (can suppress by returning false)
  4. Client beforeSubmit via flare.configure() (can suppress or modify the report)
  5. Report is sent to Flare
  6. Boundary afterSubmit

To suppress specific errors, use the client-level hooks:

flare.configure({
    beforeEvaluate: (error) => {
        if (error.message.includes('Boring error')) {
            return false; // Don't report this error
        }

        return error;
    },
});

See the client hooks documentation for more details.

Using your own error boundaries

If you have a component that already uses <svelte:boundary> to catch errors, the error won't bubble up to FlareErrorBoundary and won't be reported automatically. You can use createFlareErrorHandler() to report errors from your own boundary:

<script>
    import { createFlareErrorHandler } from '@flareapp/svelte';

    const handleError = createFlareErrorHandler();
</script>

<svelte:boundary onerror={handleError}>
    <slot />
    {#snippet failed(error, reset)}
        <p>Something went wrong. <button onclick={reset}>Retry</button></p>
    {/snippet}
</svelte:boundary>

You can also combine Flare's error boundary at the root of your app with your own boundaries further down the tree for specific sections.

Component hierarchy

When the error boundary catches an error, it sends Svelte-specific context including the component name, the full component hierarchy, and the error origin:

{
  "context": {
    "svelte": {
      "componentName": "BuggyComponent",
      "componentHierarchy": [
        "BuggyComponent",
        "NestedParent",
        "DashboardPage",
        "+layout"
      ],
      "errorOrigin": "render"
    }
  }
}

The full component hierarchy is available when the Flare preprocessor is enabled. Without the preprocessor, the hierarchy falls back to stack frame extraction and will typically contain only the component that threw.

Enabling the component hierarchy

Svelte does not expose a public API to walk the component tree. To work around this, @flareapp/svelte ships a Svelte preprocessor that injects a lightweight registration call into every component. This builds a parent-child chain using Svelte's context API (setContext / getContext), which the error boundary reads when an error is caught.

The easiest way to add it is by wrapping your config with withFlareConfig in svelte.config.js:

import { withFlareConfig } from '@flareapp/svelte/config';

export default withFlareConfig({
    // your existing config (kit, compilerOptions, etc.)
});

withFlareConfig automatically injects the preprocessor alongside any existing preprocessors. It won't inject it twice if it's already present.

You can also use flarePreprocessor() directly for manual control:

import { flarePreprocessor } from '@flareapp/svelte/config';

export default {
    preprocess: [flarePreprocessor()],
};

If you already have other preprocessors (e.g. vitePreprocess), add flarePreprocessor() to the array alongside them.

How it works

The preprocessor adds two lines to the top of every component's <script> block at build time:

import { __flareRegisterComponent } from '@flareapp/svelte';
__flareRegisterComponent('ComponentName', 'src/lib/ComponentName.svelte');

At runtime, each component:

  1. Reads the parent's registration via getContext(),
  2. Creates a node { name, file, parent } linking to that parent,
  3. Registers itself via setContext() so its children can find it.

When the error boundary catches an error, it looks up the erroring component (identified from the error's stack trace) in the registry and walks the .parent chain to build the full hierarchy.

Trade-offs

The preprocessor is optional — everything works without it, but the component hierarchy will be limited to what the stack trace reveals (usually one component).

With preprocessor Without preprocessor
Component hierarchy Full parent chain from error to root Only components visible in the stack trace (usually 1)
Runtime cost One setContext + one getContext per component mount None
Bundle size ~2 lines injected per component No change
Build step Wrap config with withFlareConfig or add preprocessor to svelte.config.js No build changes

Excluding components

If you want to skip specific files (e.g. a design system library), pass an exclude regex:

// With withFlareConfig:
withFlareConfig({ /* ... */ }, {
    exclude: /node_modules|\.stories\.svelte/,
})

// Or with flarePreprocessor directly:
flarePreprocessor({
    exclude: /node_modules|\.stories\.svelte/,
})

Without the preprocessor

Without the preprocessor, component names are extracted from the error's stack frames by looking for .svelte file references. In development builds, functionName is preferred (more reliable). In production builds, the file name is used as a fallback. componentName is the first component found, or null if no .svelte file could be identified.

Error origin

The error origin is determined by analyzing stack frame patterns. This heuristic classification helps with filtering and grouping errors:

Error Origin Description
event Error originated from an event handler (e.g. onclick, onchange, addEventListener)
effect Error originated from an asynchronous effect (e.g. queueMicrotask, Promise.then, MutationObserver)
render Error occurred during rendering (detected by .svelte files in the stack with no event/effect patterns)
unknown No Svelte-related frames found in the stack

The priority order is: event > effect > render > unknown.

Props reference

Prop Type Description
children Snippet The child content to render inside the boundary.
failed Snippet<[error: Error, reset: () => void]> Snippet to display when an error is caught. Receives the error and a reset function.
resetKeys unknown[] Values that trigger an automatic reset when changed (compared per-index via Object.is).
beforeEvaluate ({ error }) => void Called before the component context is built.
beforeSubmit ({ error, context }) => FlareSvelteContext Called before submitting. Return a (possibly modified) context.
afterSubmit ({ error, context }) => void Called after flare.report() is called (the report is sent asynchronously).
onReset (error: Error | null) => void Called when the error boundary is reset; receives the previous error (or null).
API reference Error handler
  • On this page
  • Basic usage
  • Displaying a fallback UI
  • Resetting the error boundary
  • Lifecycle hooks
  • Filtering errors
  • Using your own error boundaries
  • Component hierarchy
  • Error origin
  • Props reference

Catch errors and fix slowdowns with Flare, the full-stack application monitoring platform for Laravel, PHP & JavaScript.

  • Platform
  • Error Tracking
  • Performance Monitoring
  • Pricing
  • Support
  • Resources
  • Insights
  • Newsletter
  • Changelog
  • Documentation
  • Affiliate program
  • uptime status badge Service status
  • Terms of use
  • DPA
  • Privacy & cookie Policy
Made in by
Flare