Error monitoring for React.

With @sentry/react and a DSN from Fehlo, errors from your React app reach Fehlo with the component stack and readable source maps.

As of 21 October 2026, @sentry/react 11.8.0. We tested @sentry/browser 11.8.0 and sentry-cli 3.8.0, which the React SDK builds on, with Fehlo.

1. Install the package

Terminal
npm install @sentry/react

2. Start the SDK

Create a file instrument.js and import it first in your entry point, before any other import.

instrument.js
import * as Sentry from "@sentry/react";

Sentry.init({
  dsn: "https://<key>@app.fehlo.de/<project-id>",
  environment: "production",
  release: "my-app@1.0.0",
  dataCollection: {
    userInfo: false,
  },
});

dataCollection: { userInfo: false } stops the SDK from sending user data and IP addresses, which version 11 otherwise does. More under GDPR-compliant error tracking.

3. Capture errors from components

From React 19, hand the error hooks of createRoot to the SDK:

main.jsx
import "./instrument";
import { createRoot } from "react-dom/client";
import * as Sentry from "@sentry/react";
import App from "./App";

const root = createRoot(document.getElementById("root"), {
  onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
    console.warn("Uncaught error", error, errorInfo.componentStack);
  }),
  onCaughtError: Sentry.reactErrorHandler(),
  onRecoverableError: Sentry.reactErrorHandler(),
});
root.render(<App />);

On React 18 or older, wrap your app in an error boundary instead:

App.jsx
<Sentry.ErrorBoundary fallback={<p>Something went wrong.</p>}>
  <App />
</Sentry.ErrorBoundary>

4. Test it

Add a button that throws and click it. Errors you trigger from the browser's developer console are not captured.

App.jsx
<button type="button" onClick={() => { throw new Error("Fehlo test error"); }}>
  Send test error
</button>

The error shows up in your project's issue list within a few seconds.

5. Upload source maps

Without source maps the stack trace shows minified code. Have Vite write source maps without linking them from the bundle:

vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  build: {
    sourcemap: "hidden",
  },
});

After the build, sentry-cli writes a debug ID into each file and uploads the maps to Fehlo. Deploy the files from dist only after that, so they carry the same IDs.

Terminal
npm install --save-dev @sentry/cli

export SENTRY_URL=https://app.fehlo.de/
export SENTRY_ORG=<organisation-slug>
export SENTRY_PROJECT=<project-slug>
export SENTRY_AUTH_TOKEN=<token>

npx sentry-cli sourcemaps inject dist
npx sentry-cli sourcemaps upload --release "my-app@1.0.0" dist

Create the token in Fehlo under Settings, API tokens, with the preset "For source maps". The organisation and project slugs are in the address bar of the project settings: /<organisation>/settings/projects/<project>.

If you prefer the Vite plugin @sentry/vite-plugin, its url option sets the server. The route we tested with Fehlo is sentry-cli.

vite.config.js
sentryVitePlugin({
  url: "https://app.fehlo.de/",
  org: "<organisation-slug>",
  project: "<project-slug>",
  authToken: process.env.SENTRY_AUTH_TOKEN,
  telemetry: false,
}),

Measure performance

For page loads and requests, add to Sentry.init:

instrument.js
integrations: [Sentry.browserTracingIntegration()],
tracesSampleRate: 0.2,

Each measured page view is a transaction. Transactions count against your plan's own transaction allowance, not against your events. 0.2 means one page view in five is measured.

Questions

Nothing arrives. What should I check?

First the DSN: it has to point at app.fehlo.de. Second, whether your server or browser can reach https://app.fehlo.de (firewall, proxy, ad blocker). Third, whether this month's quota is used up; you get an email when it is. Fourth, whether sampleRate or beforeSend drops events. If only performance data is missing, this month's transactions may be used up.