A customer clicks the “Checkout” button, the spinner runs for 30 seconds, and the screen freezes. The frustrated customer leaves your website, and you have no idea what happened because the server logged nothing. This is the classic nightmare of every e-commerce website. Sentry was created to solve this exact problem. It acts as a 24/7 radar monitoring system. Whenever a line of code breaks, Sentry instantly captures the error, records device details, and sends you an alert within seconds.
Quick Start (Set Up in 5 Minutes)
Next.js and Sentry work together seamlessly. You don’t need to write configurations from scratch thanks to the automated tool provided by the development team.
Step 1: Run the Sentry Wizard
Open your terminal in the project’s root directory and run:
npx @sentry/wizard@latest -i nextjs
This command opens your browser so you can log in to your Sentry account. Next, select the Organization and Project you want to connect. The wizard will automatically install the required npm packages and create configuration files.
Step 2: Inspect the 3 Auto-Generated Config Files
Sentry creates configuration files tailored to each Next.js execution environment:
sentry.client.config.ts: Catches JavaScript crashes on the client browser.sentry.server.config.ts: Catches errors in the Node.js runtime (Server Components, Route Handlers, Server Actions).sentry.edge.config.ts: Monitors Middleware and functions running on the Edge Runtime.
Step 3: Test a Runtime Error
Create a simple button in a Client Component to trigger a test error:
"use client";
export default function TestErrorButton() {
return (
<button
onClick={() => {
throw new Error("Sentry Test: Triggering a test client-side error!");
}}
className="px-4 py-2 bg-red-600 text-white rounded font-medium"
>
Trigger Test Error
</button>
);
}
Click the button in your browser, then open the Issues tab on your Sentry Dashboard. You will see the issue appear with a detailed stack trace, browser version, OS, and the URL where the user encountered the error.
How Does Sentry Work in Full-Stack Next.js?
The Next.js App Router architecture combines client and server execution. A user request can pass through Middleware, render HTML on a Node.js server, and hydrate on the React client. An issue can arise at any point in this chain.
1. Wrap the Build Configuration with next.config
Sentry hooks directly into the Webpack/Turbopack build process via the withSentryConfig wrapper in next.config.mjs:
import { withSentryConfig } from "@sentry/nextjs";
const nextConfig = {
// Your current Next.js configuration
};
export default withSentryConfig(nextConfig, {
silent: true, // Suppress extra build logs on CI
org: "my-company",
project: "ecommerce-nextjs",
widenClientFileUpload: true,
hideSourceMaps: true,
});
2. Manually Capture Exceptions
Don’t rely solely on unhandled exceptions. In critical logic like payment API calls or database queries, wrap your code in try...catch and attach metadata for easier debugging:
import * as Sentry from "@sentry/nextjs";
export async function fetchUserOrders(userId: string) {
try {
const res = await db.query("SELECT * FROM orders WHERE user_id = $1", [userId]);
return res.rows;
} catch (error) {
Sentry.captureException(error, {
extra: {
userId,
query: "SELECT * FROM orders WHERE user_id = $1",
timestamp: new Date().toISOString()
},
});
return null;
}
}
3. Attach User Context
When a VIP customer submits a support ticket, you need to immediately look up their request history. Attach user context to Sentry right after login:
Sentry.setUser({
id: user.id,
email: user.email,
username: user.username,
});
Distributed Tracing and Performance Monitoring
Sometimes the system doesn’t crash, but a payment API takes 8 seconds to respond. Cart abandonment rates will skyrocket. This is where Performance Monitoring and Distributed Tracing deliver real value.
What is Distributed Tracing?
A checkout transaction consists of several hops: Browser sends request -> Next.js Server handles it -> Stripe gateway is called -> Data is written to Postgres. Distributed Tracing consolidates this entire journey into a single Gantt chart (Trace). This allows you to immediately see whether the Stripe call took 5.2s or an unindexed SQL query caused a bottleneck.
Sample configuration in sentry.client.config.ts and sentry.server.config.ts:
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Capture 100% of traces in development, and 10% (0.1) in production to save quota
tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1.0,
// Record user interactions prior to a crash (Session Replay)
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.05,
});
Filter Sensitive Data Before Sending
Security compliance is non-negotiable. Never expose JWT tokens, session cookies, or credit card information on your Sentry dashboard. Use the beforeSend hook to sanitize your data:
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
beforeSend(event) {
if (event.request?.headers) {
delete event.request.headers["authorization"];
delete event.request.headers["cookie"];
}
return event;
},
});
Battle-Tested Production Best Practices
After deploying Sentry across multiple production systems, here are 4 key takeaways:
- Upload Accurate Source Maps: Add
SENTRY_AUTH_TOKENto your CI/CD environment variables (GitHub Actions or Vercel). Without source maps, stack traces will only display unreadable minified code likea.b(c) at 412-df89.js:1:182. - Inspect Data Payloads: When debugging event contexts or formatting JSON strings attached to errors, use online utilities like
toolcraft.app(JSON Formatter / Regex Tester sections) to quickly process raw data. - Set Sensible Alert Thresholds: Avoid email fatigue from every minor warning. Create rules to trigger Slack/Discord alerts only for new issues (New Issue) or when an existing error spikes over 50 times per minute.
- Optimize Sampling Quotas: Sentry’s free tier includes 5,000 errors and 10,000 transactions per month. For a site with 500,000 page views, lower
tracesSampleRateto0.01or0.02on standard pages and increase sampling on high-value routes like Checkout.

