Error monitoring for Next.js.
With @sentry/nextjs, Fehlo captures errors from the browser, server components, route handlers and middleware. The manual setup is five files.
As of 21 October 2026, @sentry/nextjs 11.8.0, Next.js 14 to 16 with the App Router.
1. Install the package
npm install @sentry/nextjsThe wizard npx @sentry/wizard -i nextjs signs in to the target server, and we have not tested it with Fehlo. The manual setup takes five files, all in the project root or in src/.
2. Browser
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "https://<key>@app.fehlo.de/<project-id>",
dataCollection: {
userInfo: false,
},
});
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;The onRouterTransitionStart export measures client-side navigations.
3. Server and edge
The same configuration for the Node.js and the edge runtime:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "https://<key>@app.fehlo.de/<project-id>",
dataCollection: {
userInfo: false,
},
});import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "https://<key>@app.fehlo.de/<project-id>",
dataCollection: {
userInfo: false,
},
});Next.js loads them through instrumentation.ts. onRequestError reports errors from server components, route handlers and middleware.
import * as Sentry from "@sentry/nextjs";
export async function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
await import("./sentry.server.config");
}
if (process.env.NEXT_RUNTIME === "edge") {
await import("./sentry.edge.config");
}
}
export const onRequestError = Sentry.captureRequestError;4. Rendering errors
Errors that break rendering of the whole app are caught by app/global-error.tsx:
"use client";
import * as Sentry from "@sentry/nextjs";
import NextError from "next/error";
import { useEffect } from "react";
export default function GlobalError({
error,
}: {
error: Error & { digest?: string };
}) {
useEffect(() => {
Sentry.captureException(error);
}, [error]);
return (
<html>
<body>
<NextError statusCode={0} />
</body>
</html>
);
}5. Build and source maps
withSentryConfig uploads source maps during the build. Since version 11 you import it from @sentry/nextjs/config. The sentryUrl option points it at Fehlo instead of sentry.io.
import type { NextConfig } from "next";
import { withSentryConfig } from "@sentry/nextjs/config";
const nextConfig: NextConfig = {};
export default withSentryConfig(nextConfig, {
sentryUrl: "https://app.fehlo.de/",
org: "<organisation-slug>",
project: "<project-slug>",
authToken: process.env.SENTRY_AUTH_TOKEN,
silent: !process.env.CI,
widenClientFileUpload: true,
});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>. Set the token as SENTRY_AUTH_TOKEN in CI, not in code.
6. Test it
Add a page with a button that throws and open it in the browser:
"use client";
export default function FehloTest() {
return (
<button type="button" onClick={() => { throw new Error("Fehlo test error"); }}>
Test error
</button>
);
}Measure performance
Add tracesSampleRate: 0.2, to all three Sentry.init calls. In Fehlo, transactions count against their own allowance, not against your events.
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.