How to Set Up Error Tracking with Sentry in a Next.js Application

How to Set Up Error Tracking with Sentry in a Next.js Application

by | May 25, 2026 | Uncategorized | 0 comments

Why You Need Sentry in Your Next.js Application

Production bugs are inevitable. The difference between a team that fixes issues in minutes and one that takes days often comes down to one thing: error tracking. If you are building with Next.js, integrating Sentry gives you real-time visibility into errors happening on both the client and server, complete with stack traces, breadcrumbs, and contextual data.

In this hands-on tutorial, we will walk through a complete Sentry Next.js setup from scratch. By the end, you will have full error monitoring across client-side rendering, server-side rendering, API routes, and edge functions, plus custom error boundaries and alert rules so your team never misses a critical issue.

Prerequisites

Before we start, make sure you have the following ready:

  • A Next.js project (version 13.2 or higher; this guide uses Next.js 15+)
  • Node.js 18 or later
  • A Sentry account (free tier works fine)
  • A Sentry project created and your DSN (Data Source Name) available
error tracking dashboard code

Step 1: Install the Sentry Next.js SDK

The fastest way to get started is by using the official Sentry wizard. Open your terminal in the root of your Next.js project and run:

npx @sentry/wizard@latest -i nextjs

The wizard will automatically:

  1. Install the @sentry/nextjs package
  2. Create the required configuration files
  3. Set up source map uploads
  4. Optionally add example error buttons for testing

If you prefer a manual installation, run:

npm install @sentry/nextjs

or with Yarn:

yarn add @sentry/nextjs

Step 2: Configure Sentry

After installation, you need three configuration files in the root of your project. If the wizard created them, review and customize them. If you installed manually, create them now.

sentry.client.config.ts

This file initializes Sentry on the client side (browser).

import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 1.0,
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  integrations: [
    Sentry.replayIntegration(),
    Sentry.browserTracingIntegration(),
  ],
  environment: process.env.NODE_ENV,
});

sentry.server.config.ts

This file initializes Sentry on the server side (Node.js runtime).

import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
  environment: process.env.NODE_ENV,
});

sentry.edge.config.ts

If you use Next.js edge functions or middleware, create this file as well:

import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
  environment: process.env.NODE_ENV,
});

Summary of Configuration Files

File Purpose Runtime
sentry.client.config.ts Browser-side error and performance tracking Browser
sentry.server.config.ts Server-side error tracking (SSR, API routes) Node.js
sentry.edge.config.ts Edge runtime tracking (middleware, edge API) Edge

Step 3: Update next.config.js

Wrap your existing Next.js configuration with the withSentryConfig function. This is essential for source map uploads and proper build-time instrumentation.

import { withSentryConfig } from "@sentry/nextjs";

const nextConfig = {
  // your existing Next.js config
};

export default withSentryConfig(nextConfig, {
  org: "your-sentry-org",
  project: "your-sentry-project",
  silent: !process.env.CI,
  widenClientFileUpload: true,
  tunnelRoute: "/monitoring",
  disableLogger: true,
  automaticVercelMonitors: true,
});

Key Options Explained

  • widenClientFileUpload: Uploads a broader set of client-side source files for better stack traces.
  • tunnelRoute: Routes Sentry data through your own domain, which helps avoid ad blockers. More on this below.
  • silent: Suppresses build logs outside of CI environments.
  • disableLogger: Removes Sentry logger statements from your production bundle to reduce size.

Step 4: Set Up Environment Variables

Add the following to your .env.local file (and your deployment platform’s environment settings):

NEXT_PUBLIC_SENTRY_DSN=https://[email protected]/0
SENTRY_DSN=https://[email protected]/0
SENTRY_ORG=your-org-slug
SENTRY_PROJECT=your-project-slug
SENTRY_AUTH_TOKEN=your-auth-token

To generate your SENTRY_AUTH_TOKEN:

  1. Go to Settings > Auth Tokens in your Sentry dashboard
  2. Click Create New Token
  3. Select at minimum the project:releases and org:read scopes
  4. Copy the token and store it securely

Step 5: Configure Source Maps

Source maps are what turn minified production stack traces into readable code with exact file names and line numbers. Without them, debugging production errors is painful.

If you used withSentryConfig as shown above, source maps are automatically uploaded during your build process. To verify this is working:

  1. Run a production build: npm run build
  2. Check the build output for Sentry source map upload messages
  3. In the Sentry dashboard, go to Settings > Source Maps and confirm the artifacts are present

Important: Make sure your SENTRY_AUTH_TOKEN is available in your CI/CD environment. Without it, source maps will not upload.

Hiding Source Maps from Users

You probably do not want to expose your source maps publicly. Add this to your next.config.js:

const nextConfig = {
  productionBrowserSourceMaps: false,
};

Sentry will still receive the source maps, but they will not be served to end users.

Step 6: Add Custom Error Boundaries

Next.js provides built-in error handling with the App Router’s error.tsx files. Sentry integrates with these seamlessly, but you should create a global error boundary to catch unhandled errors and report them properly.

Global Error Page (App Router)

Create or update app/global-error.tsx:

"use client";

import * as Sentry from "@sentry/nextjs";
import { useEffect } from "react";

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  useEffect(() => {
    Sentry.captureException(error);
  }, [error]);

  return (
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={() => reset()}>Try again</button>
      </body>
    </html>
  );
}

Route-Level Error Boundary

For more granular handling, add an error.tsx file inside any route segment:

"use client";

import * as Sentry from "@sentry/nextjs";
import { useEffect } from "react";

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  useEffect(() => {
    Sentry.captureException(error);
  }, [error]);

  return (
    <div>
      <p>An error occurred in this section.</p>
      <button onClick={() => reset()}>Retry</button>
    </div>
  );
}

Capturing Errors Manually

In some cases, you want to report errors without crashing the UI. Use Sentry.captureException in try/catch blocks:

import * as Sentry from "@sentry/nextjs";

async function fetchData() {
  try {
    const res = await fetch("/api/data");
    if (!res.ok) throw new Error("Failed to fetch data");
    return await res.json();
  } catch (error) {
    Sentry.captureException(error);
    return null;
  }
}

Step 7: Track Server-Side and API Route Errors

One of the biggest advantages of the Sentry Next.js SDK is that it automatically instruments server-side rendering and API routes. However, you can enhance tracking by adding custom context.

API Route Example (App Router)

import { NextResponse } from "next/server";
import * as Sentry from "@sentry/nextjs";

export async function GET() {
  try {
    // your logic here
    const data = await getDataFromDatabase();
    return NextResponse.json(data);
  } catch (error) {
    Sentry.captureException(error, {
      tags: { section: "api", route: "/api/data" },
    });
    return NextResponse.json(
      { error: "Internal Server Error" },
      { status: 500 }
    );
  }
}

Server Components

Errors in React Server Components are also captured automatically. For additional context, you can wrap logic with Sentry spans:

import * as Sentry from "@sentry/nextjs";

export default async function Page() {
  return await Sentry.withServerActionInstrumentation(
    "loadDashboardData",
    async () => {
      const data = await fetchDashboardData();
      return <Dashboard data={data} />;
    }
  );
}

Step 8: Set Up the Sentry Tunnel (Bypass Ad Blockers)

Many ad blockers and browser privacy extensions block requests to Sentry’s ingestion endpoints. The tunnel route solves this by proxying Sentry events through your own domain.

If you added tunnelRoute: "/monitoring" in your withSentryConfig options, this is already active. All Sentry events will be sent to yourdomain.com/monitoring instead of directly to sentry.io, making them invisible to ad blockers.

No additional server code is needed. The SDK handles everything.

Step 9: Configure Alerts in Sentry

Catching errors is only half the battle. You need to know about them immediately. Here is how to set up alerts in the Sentry dashboard.

Creating an Alert Rule

  1. Navigate to Alerts > Create Alert in your Sentry project
  2. Choose Issues as the alert type
  3. Set conditions, for example:
    • When a new issue is created
    • When an issue is seen more than 10 times in 1 hour
    • When an issue affects more than 5% of sessions
  4. Choose your notification channel: email, Slack, Microsoft Teams, PagerDuty, or webhooks
  5. Save the alert rule

Recommended Alert Configuration

Alert Type Trigger Best For
New Issue First occurrence of an error Catching regressions immediately after deploys
Frequency Error count exceeds threshold Detecting spikes in recurring issues
Crash Rate Session crash rate rises above X% Monitoring overall app stability
Performance Transaction duration exceeds threshold Spotting slow pages or API endpoints

Step 10: Verify Your Setup

Time to make sure everything works. Add a test button to any page in your application:

"use client";

export default function TestSentry() {
  return (
    <button
      onClick={() => {
        throw new Error("Sentry test error - client side");
      }}
    >
      Trigger Test Error
    </button>
  );
}
  1. Click the button in your browser
  2. Open your Sentry dashboard
  3. You should see the error appear within seconds, complete with a stack trace pointing to your original source code

For server-side testing, create a test API route:

import { NextResponse } from "next/server";

export async function GET() {
  throw new Error("Sentry test error - server side");
  return NextResponse.json({ ok: true });
}

Visit the route in your browser and confirm the error shows up in Sentry with server-side context.

Troubleshooting Common Issues

Here are the problems developers run into most often with Sentry Next.js setup, and how to fix them:

Errors Not Appearing in Sentry

  • Double-check your DSN is correct and the environment variable is loaded
  • Make sure Sentry.init() is called before any other code runs
  • Check browser dev tools for blocked network requests (ad blockers)
  • Verify the tunnel route is configured if you suspect blocking

Source Maps Not Working

  • Confirm SENTRY_AUTH_TOKEN is set in your build environment
  • Run npm run build and look for upload confirmation in the output
  • In Sentry, go to Settings > Source Maps and check that artifacts exist for the correct release

Build Errors After Adding Sentry

  • Ensure you are using a compatible version of @sentry/nextjs for your Next.js version
  • If you are on Next.js 15 or later, use @sentry/nextjs version 8.x or higher
  • Check for conflicts with other Webpack plugins or custom configurations

Performance Impact Concerns

  • Adjust tracesSampleRate to a lower value (e.g., 0.2) in production to reduce overhead
  • Set replaysSessionSampleRate to 0.1 or lower unless you specifically need session replays

Best Practices for Production

Once your Sentry Next.js setup is complete, follow these practices to get the most value:

  • Tag errors with context: Add user IDs, feature flags, or route information using Sentry.setTag() and Sentry.setUser()
  • Use releases: Associate errors with specific deployments so you can track regressions per release
  • Set up Slack or Teams integration: Get instant notifications for critical errors without checking the dashboard
  • Review errors weekly: Triage and resolve issues regularly to keep your error feed manageable
  • Customize fingerprinting: Group related errors together to avoid noise from the same underlying bug
  • Use beforeSend: Filter out known non-actionable errors before they count against your quota
Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  beforeSend(event) {
    // Filter out specific errors
    if (event.exception?.values?.[0]?.value?.includes("ResizeObserver")) {
      return null;
    }
    return event;
  },
});

Conclusion

Setting up Sentry in a Next.js application gives your team a significant advantage when it comes to finding and fixing production issues. With client-side tracking, server-side instrumentation, source map integration, custom error boundaries, and alert rules all in place, you will catch problems before your users even report them.

The entire setup takes about 15 to 30 minutes, and the payoff is immediate. The next time something breaks in production, you will have the full error context, the exact line of code, and a timeline of events leading up to the failure.

At Box Software, we integrate Sentry into every Next.js project we build. If you need help setting up error tracking or improving the reliability of your web application, get in touch with our team.

Frequently Asked Questions

Is Sentry free to use with Next.js?

Yes. Sentry offers a free Developer plan that includes error tracking, performance monitoring, and session replays with generous monthly quotas. It is more than enough for small to medium projects. Paid plans are available for higher volumes and additional features.

What is the minimum Next.js version required for Sentry?

The @sentry/nextjs SDK currently requires Next.js 13.2 or higher. For the best experience with the App Router and Server Components, we recommend using Next.js 14 or 15.

Does Sentry slow down my Next.js application?

The performance impact is minimal. Sentry adds a small amount of JavaScript to your client bundle and runs asynchronously. You can further reduce overhead by lowering the tracesSampleRate and replaysSessionSampleRate in production.

Can I use Sentry with the Next.js Pages Router?

Absolutely. The @sentry/nextjs SDK supports both the App Router and the Pages Router. For the Pages Router, you would use the _error.tsx file for your custom error boundary instead of global-error.tsx.

How do I set up Sentry for Next.js on Vercel?

Add your SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT, and NEXT_PUBLIC_SENTRY_DSN as environment variables in your Vercel project settings. The rest of the configuration stays the same. If you enabled automaticVercelMonitors in withSentryConfig, Sentry will also track your Vercel cron jobs.

What is a Sentry tunnel and do I need one?

A Sentry tunnel routes error data through your own domain instead of sending it directly to sentry.io. This prevents ad blockers from intercepting the requests. If your application has end users who might use ad blockers, enabling the tunnel is strongly recommended.