Your App Is Crashing and You Don't Know Why — Intro to Error Tracking
Your App Is Crashing and You Don't Know Why — Intro to Error Tracking
The Problem
It's 2 AM and you get a DM.
"Hey, is your site down? I've been trying to sign up for 20 minutes and it keeps breaking."
You bolt upright, flip open your laptop, and load your app. It works fine for you. You check Vercel — the deployment looks green. You check your database — the connection string is there. Everything seems fine.
Then another message. And another. By morning, your Twitter mentions are a small graveyard of frustrated users, and you've lost signups you'll never be able to count because you have no idea when it started, how many people hit it, or what on earth broke.
Sound familiar? This is the story of almost every first production app — and it's not your fault. Nobody teaches you this stuff. You learned to build features, not to survive them.
Here's the uncomfortable truth: your app is probably throwing errors right now. Real users on real devices in real conditions — edge cases you never tested, network blips, database timeouts, a browser extension that conflicts with your auth flow — these are silently failing with zero visibility on your end. You're flying blind.
The good news: this is one of the most fixable problems in software. It takes about fifteen minutes to go from zero observability to knowing the exact file, line number, user, and browser where an error occurred. Let's do it.
The Fix
We're going to set up Sentry in your Next.js app on Vercel. Sentry captures every unhandled exception — client-side, server-side, and edge — and sends it to a dashboard where you can see exactly what broke, who it affected, and what they were doing when it happened.
Step 1: Create a free Sentry account
Go to sentry.io and sign up. Create a new Next.js project. Sentry will give you a DSN (Data Source Name) — a URL that's your project's unique identifier. Keep that tab open.
Step 2: Run the wizard
In your project directory, run:
npx @sentry/wizard@latest -i nextjs
The wizard will open a browser window to authenticate with your Sentry account, let you pick your project, and ask which features you want. For Day 1, select Error Monitoring and Session Replay. That's it — skip the rest for now.
When it finishes, you'll see several new files in your project:
your-app/
├── instrumentation-client.ts ← browser-side Sentry init
├── sentry.server.config.ts ← Node.js server-side init
├── sentry.edge.config.ts ← edge runtime init
├── instrumentation.ts ← wires server + edge configs into Next.js
└── app/
└── sentry-example-page/ ← test page to verify your setup
Your next.config.ts will also be updated automatically to wrap your config with withSentryConfig.
Step 3: Review what was generated
Open instrumentation-client.ts. It will look something like this:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Capture 10% of sessions for performance tracing in production
tracesSampleRate: 0.1,
// Capture full session replay when an error occurs
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
integrations: [Sentry.replayIntegration()],
});
And sentry.server.config.ts:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 0.1,
});
The instrumentation.ts file is the glue that plugs everything into Next.js's instrumentation hook:
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");
}
}
// Captures errors from Server Components, middleware, and API routes
export const onRequestError = Sentry.captureRequestError;
Step 4: Add your environment variables
In your Vercel project dashboard, go to Settings → Environment Variables and add:
NEXT_PUBLIC_SENTRY_DSN=https://your-dsn-here@sentry.io/123456
SENTRY_AUTH_TOKEN=your-auth-token-here
The auth token lets Sentry upload source maps so you see readable stack traces instead of minified gibberish. You can generate a token in Sentry under Settings → Auth Tokens.
Add the same variables to your local .env.local for development. Add SENTRY_AUTH_TOKEN to .gitignore — it should never be committed.
Step 5: Verify it works
Start your dev server, navigate to /sentry-example-page, and click the "Throw error" button. Within a few seconds, you should see the error appear in your Sentry dashboard. If you do, you're live.
Deploy to Vercel, and from this point forward, every unhandled error your users encounter will be logged, grouped, and waiting for you in Sentry — with a full stack trace, browser info, and a replay of what the user was doing.
One extra thing: handle errors in Server Actions
If you're using Next.js Server Actions, errors thrown inside them aren't automatically captured by the instrumentation hook in all versions. Wrap them explicitly:
"use server";
import * as Sentry from "@sentry/nextjs";
export const submitForm = Sentry.withServerActionInstrumentation(
"submitForm",
async (formData: FormData) => {
// your action logic here
const result = await saveToDatabase(formData);
return result;
}
);
Example Prompts
You can use these prompts with your AI coding assistant to implement or extend error tracking in your app.
Prompt 1 — Initial Sentry Setup
"I have a Next.js 15 app using the App Router deployed on Vercel. Walk me through setting up Sentry for error tracking. I want to capture client-side errors, server-side errors from API routes and Server Components, and errors from Server Actions. Show me the instrumentation-client.ts, sentry.server.config.ts, and instrumentation.ts files I need, and explain what each one does."
Prompt 2 — Custom Error Context
"I'm using Sentry in my Next.js app. When an error occurs, I want to automatically include the current user's ID and email so I can see exactly which users are affected. Show me how to call Sentry.setUser() in a layout component that runs server-side, and also in a client component that runs on the browser, using my existing auth session."
Prompt 3 — Alert Setup and Noise Reduction
"I've just set up Sentry on my Next.js app. I want to get a Slack notification the first time a new error occurs, but not spam my channel with every repeat occurrence. Walk me through creating an alert rule in Sentry that fires once per new unique error and mutes for 10 minutes after that. Also help me set up a filter to ignore browser extension errors and network timeouts that aren't actionable."
The Checklist
Don't go to sleep until you've verified each of these:
-
@sentry/nextjsis installed and the wizard has run successfully -
instrumentation-client.ts,sentry.server.config.ts, andsentry.edge.config.tsexist in your project root -
NEXT_PUBLIC_SENTRY_DSNis set in Vercel environment variables (Production, Preview, and Development) -
SENTRY_AUTH_TOKENis set in Vercel environment variables and is not committed to git - You've triggered a test error on
/sentry-example-pageand confirmed it appeared in your Sentry dashboard -
onRequestError = Sentry.captureRequestErroris exported frominstrumentation.ts(this captures Server Component errors) - Any Server Actions that do important work are wrapped with
Sentry.withServerActionInstrumentation() - You've set up at least one Sentry alert — email or Slack — so you're notified when new errors fire in production
- You've deployed to Vercel and verified that source maps uploaded (check Sentry → your project → Source Maps)
If source maps didn't upload, check that SENTRY_AUTH_TOKEN is present in your Vercel environment and that withSentryConfig is wrapping your next.config.ts export.
Ask The Guild
You've got Sentry running. You're seeing your first real errors. Now here's the question worth sitting with:
What's the first real error you discovered in production that you had no idea was happening?
Drop it in the Discord. Whether it's a database query that only fails for users in certain timezones, a payment flow that breaks on Safari, or a Server Action that silently swallowed every form submission for three days — share it. The most useful thing we can build together is a shared sense of what "production" actually looks like.
You shipped something. That's already more than most. Now let's make sure it keeps running.