# Sentry Next.js: three runtimes, three init files, one wrapped config
## Use the wizard
```
npx @sentry/wizard@latest -i nextjs
```
It creates separate init files because Next.js runs your code in three environments:
- Client: `instrumentation-client.ts` (browser)
- Server: `sentry.server.config.ts` (Node.js)
- Edge: `sentry.edge.config.ts` (edge runtime)
And `instrumentation.ts` registers them:
```ts
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;
```
## The wrapped next.config
```ts
import { withSentryConfig } from "@sentry/nextjs/config";
export default withSentryConfig(nextConfig, {
org: "[your org slug]",
project: "[your project slug]",
authToken value process.env.SENTRY_AUTH_TOKEN, // secret, CI only, never client-exposed
tunnelRoute: "/sentry-tunnel", // routes events through your server, dodges adblockers
silent: !process.env.CI,
});
```
`org` and `project` here are for build-time source map uploads, which is why they sit next to the auth token. This is also where the classic mixup happens: the DSN goes in the three init files, the AUTH TOKEN goes here. Swapping them breaks both.
## Sample rates per environment
The wizard generates `tracesSampleRate: process.env.NODE_ENV === "development" ? 1.0 : 0.1`. Keep that shape. Setting 1.0 unconditionally is the fastest way to burn a month of span quota in a week.
## Don't forget global-error.tsx
The wizard adds `app/global-error.tsx` to catch React rendering errors in App Router. If you hand-rolled the setup and rendering crashes are missing from Sentry, that file is what you forgot.