# Version 2 of our JavaScript client libraries

> Source: <https://flareapp.io/blog/version-2-of-our-javascript-client-libraries>
> Published: 2026-05-12 09:00:06+00:00

We just shipped new major versions of all four JavaScript packages: [ @flareapp/js](https://github.com/spatie/flare-client-js/tree/main/packages/js),

[,](https://github.com/spatie/flare-client-js/tree/main/packages/react)

`@flareapp/react`

[, and](https://github.com/spatie/flare-client-js/tree/main/packages/vue)

`@flareapp/vue`

[.](https://github.com/spatie/flare-client-js/tree/main/packages/vite)

`@flareapp/vite`

The framework packages went from minimal error forwarders to full-featured integrations, the core client talks to a new ingestion endpoint, and the Vite plugin handles failure gracefully.

### What changed in the core client

`@flareapp/js`

now uses a new, faster ingestion endpoint with a different payload format. Sensitive query-string parameters like `password`

, `token`

, and `secret`

are automatically redacted from URLs in your error reports. Browser context (URL, viewport, cookies, user agent) is collected on every report without any setup on your end.

There's also a new `sampleRate`

option, the default value is 1 (record all errors). If you're dealing with high traffic and don't need every single error reported you can do the following:

```
flare.light('your-api-key');
flare.configure({ sampleRate: 0.5 }); // report ~50% of errors
```

### React: from catch-and-forward to full error recovery

In v1, `FlareErrorBoundary`

did one thing: catch the error and forward it to Flare. When something broke, your users saw a blank screen. Or you had to implement your own error boundary using the JS client, making the use of the react client unnecessary.

``` js
// v1: catch and forward, nothing more
import { FlareErrorBoundary } from '@flareapp/react';

<FlareErrorBoundary>
    <App />
</FlareErrorBoundary>
// Error happens -> component tree disappears -> white screen
```

v2 turns the boundary into an error recovery component. You get fallback UI, a reset mechanism, and lifecycle hooks to control what gets reported:

``` js
import { FlareErrorBoundary } from '@flareapp/react';

<FlareErrorBoundary
    fallback={({ error, resetErrorBoundary }) => (
        <div>
            <p>Something went wrong: {error.message}</p>
            <button onClick={resetErrorBoundary}>Try again</button>
        </div>
    )}
    resetKeys={[location.pathname]}
    beforeEvaluate={() => {
        flare.addContext('page', 'checkout');
    }}
>
    <App />
</FlareErrorBoundary>
```

`resetKeys`

mirrors the API from [react-error-boundary](https://github.com/bvaughn/react-error-boundary): when any value in the array changes (a route navigation, a retry counter), the boundary resets automatically and your component tree re-renders. No manual wiring needed.

The `fallback`

prop accepts either a React node or a render function. The render function gives you the caught `error`

, the parsed `componentStack`

, and a `resetErrorBoundary`

callback.

For React 19 projects using `createRoot`

, there's a new `flareReactErrorHandler()`

that plugs directly into the error callbacks:

``` js
import { flareReactErrorHandler } from '@flareapp/react';

const root = createRoot(document.getElementById('root'), {
    onCaughtError: flareReactErrorHandler(),
    onUncaughtError: flareReactErrorHandler(),
});
```

Component stacks are now parsed into structured frames with file, line, and column info, giving Flare the data it needs to show you a component tree (in a JSON format for now).

### Vue: error boundaries, route context, and props capture

v1 was a thin `app.config.errorHandler`

wrapper:

``` js
// v1: set the error handler, nothing else
import { flareVue } from '@flareapp/vue';
app.use(flareVue);
```

v2 accepts options, captures Vue Router context automatically, and can forward warnings in development:

``` js
import { flareVue } from '@flareapp/vue';

app.use(flareVue, {
    captureWarnings: true,
    attachProps: true,
    propsDenylist: /password|secret|token/i,
    beforeSubmit: ({ error, context }) => {
        console.log(`Reporting: ${error.message}`);
        return context;
    },
});
```

And like React, Vue gets its own `FlareErrorBoundary`

component with a scoped `#fallback`

slot:

``` js
<script setup>
import { FlareErrorBoundary } from '@flareapp/vue';
</script>

<template>
    <FlareErrorBoundary :reset-keys="[route.fullPath]">
        <SomeComponent />
        <template #fallback="{ error, componentHierarchy, resetErrorBoundary }">
            <p>Something went wrong: {{ error.message }}</p>
            <p>Component trail: {{ componentHierarchy.join(' > ') }}</p>
            <button @click="resetErrorBoundary">Try again</button>
        </template>
    </FlareErrorBoundary>
</template>
```

The fallback slot exposes the error, the full component hierarchy as an array, parsed hierarchy frames (with props if `attachProps`

is enabled), and the reset callback.

One breaking change: Vue 2 support is dropped. If you're still on Vue 2, pin `@flareapp/vue@1`

.

### Vite plugin

`@flareapp/vite`

now retries failed sourcemap uploads with exponential backoff. A single failed upload no longer aborts the rest. You can also skip uploads entirely by setting `SKIP_SOURCEMAPS=true`

, which is useful for CI jobs that don't need them.

### Upgrading

Install the latest versions:

```
# React projects
npm install @flareapp/js@latest @flareapp/react@latest @flareapp/vite@latest

# Vue projects
npm install @flareapp/js@latest @flareapp/vue@latest @flareapp/vite@latest
```

Most of the API surface stayed the same. `light()`

, `configure()`

, `report()`

, `glow()`

, `addContext()`

, `addContextGroup()`

, `test()`

all work like before.

What did change:

**Two config keys were renamed.** If you use `configure()`

with custom URLs or sourcemap versions, update the key names:

```
-reportingUrl: 'https://...',
+ingestUrl: 'https://...',
-sourcemapVersion: 'abc123',
+sourcemapVersionId: 'abc123',
```

**Deprecated property setters are gone.** If you were setting hooks or stage via assignment, move them into `configure()`

:

``` js
-flare.beforeEvaluate = (error) => error;
-flare.beforeSubmit = (report) => report;
-flare.stage = 'production';
+flare.configure({
 beforeEvaluate: (error) => error,
 beforeSubmit: (report) => report,
 stage: 'production',
+});
```

** reportMessage signature changed.** The third parameter was

`exceptionClass`

(an arbitrary string); it's now `level`

(a `MessageLevel`

like `'info'`

or `'warning'`

) in the second position:

```
-flare.reportMessage('Something happened', { orderId: 42 }, 'Log');
+flare.reportMessage('Something happened', 'warning', { orderId: 42 });
```

**Report payload fields are now camelCase.** If your `beforeSubmit`

callback inspects the report object, the field names changed:

| v1 | v2 |
|---|---|
`report.exception_class` |
`report.exceptionClass` |
`report.seen_at` |
`report.seenAtUnixNano` |
`report.context` |
`report.attributes` |
`report.glows` |
`report.events` |
`report.stacktrace[i].line_number` |
`report.stacktrace[i].lineNumber` |

The full migration guide covers every breaking change: [v1 to v2 migration guide](https://github.com/spatie/flare-client-js/blob/main/docs/v1-to-v2-migration.md).

The docs have been updated with full guides for each package:

[Back to overview](https://flareapp.io/blog)

## Continue reading

[
Flare news
·
April 30, 2026
](https://flareapp.io/blog/flare-livewire)

## Flare ❤️ Livewire

Flare has deep Livewire visibility: components nested in traces with full hierarchy, per-phase timing (mount, hydrate, render, dehydrate), aggregated component views with bidirectional links, rich error context, and a lot more. Let us show you how Flare can assist in debugging your Livewire project.

Ruben

[
Deep Dives
·
April 22, 2026
](https://flareapp.io/blog/integration-testing-our-laravel-package-with-a-real-server-and-queue)

## Integration testing our Laravel package with a real server and queue

When unit tests aren't enough. We started testing the Laravel Flare package against a real application in order to verify that our code works using orchestra workbench. Here's how we did it.

Ruben

## Subscribe to Backtrace, our quarterly Flare newsletter

No spam, just news & product updates
