How to Set Up Error Tracking (2026)
Production errors are inevitable. Error tracking ensures you know about them before your users complain. Here's how to implement it properly.
Why Error Tracking Matters
Console logs don't help in production. Error tracking captures:
- Stack traces with source maps
- User context (who experienced the error)
- Breadcrumbs (what led to the error)
- Environment and browser info
- Error frequency and affected users
Option 1: Sentry (Recommended)
npm install @sentry/nextjs
npx @sentry/wizard@latest -i nextjs
Basic Setup
// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs'
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NODE_ENV,
// Sample rate (1.0 = 100% of errors)
tracesSampleRate: 1.0,
// Don't send errors in development
enabled: process.env.NODE_ENV === 'production',
})
Adding Context
import * as Sentry from '@sentry/nextjs'
// Set user context after login
Sentry.setUser({
id: user.id,
email: user.email,
username: user.name,
})
// Add custom tags
Sentry.setTag('tenant_id', tenant.id)
Sentry.setContext('subscription', {
plan: user.plan,
status: user.subscriptionStatus,
})
Manual Error Capture
try {
await riskyOperation()
} catch (error) {
Sentry.captureException(error, {
tags: { operation: 'payment_processing' },
extra: { orderId, amount },
})
throw error // or handle gracefully
}
Breadcrumbs (What Led to the Error)
// Automatic breadcrumbs for:
// - Network requests
// - User clicks
// - Console logs
// - Navigation
// Manual breadcrumb
Sentry.addBreadcrumb({
category: 'payment',
message: 'User initiated checkout',
level: 'info',
data: { cartValue: 99.99 },
})
Option 2: BetterStack (Logs + Errors)
import { Logtail } from '@logtail/node'
const logtail = new Logtail(process.env.LOGTAIL_TOKEN)
logtail.error('Payment failed', {
userId: user.id,
orderId: order.id,
error: error.message,
})
Server-Side Error Tracking (API Routes)
// app/api/posts/route.ts
import * as Sentry from '@sentry/nextjs'
export async function POST(req: Request) {
try {
const data = await req.json()
const post = await createPost(data)
return Response.json(post)
} catch (error) {
Sentry.captureException(error, {
tags: { route: '/api/posts' },
extra: { requestBody: await req.text() },
})
return Response.json(
{ error: 'Failed to create post' },
{ status: 500 }
)
}
}
React Error Boundaries
'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>
<h2>Something went wrong!</h2>
<button onClick={reset}>Try again</button>
</div>
)
}
Source Maps (Critical!)
Without source maps, stack traces show minified code. Useless.
// next.config.js
module.exports = {
sentry: {
hideSourceMaps: true, // Don't expose to users
widenClientFileUpload: true, // Upload all source maps
},
}
Sentry automatically uploads source maps during build.
Alerts and Notifications
Sentry → Integrations → Slack
Configure:
- New issue alert (first occurrence)
- High-volume alert (>100 errors/hour)
- Regression alert (error returns after being resolved)
Filtering Noise
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
beforeSend(event, hint) {
// Ignore specific errors
if (event.exception?.values?.[0]?.type === 'ChunkLoadError') {
return null // Don't send to Sentry
}
// Filter by user
if (event.user?.email?.includes('@yourcompany.com')) {
return null // Ignore internal team errors
}
return event
},
ignoreErrors: [
'ResizeObserver loop limit exceeded',
'Non-Error promise rejection captured',
],
})
Performance Monitoring
import * as Sentry from '@sentry/nextjs'
const transaction = Sentry.startTransaction({
name: 'Process Payment',
op: 'payment',
})
try {
const span = transaction.startChild({ op: 'stripe.charge' })
await stripe.charges.create(...)
span.finish()
} finally {
transaction.finish()
}
FAQ
Do I need error tracking for a side project?
Yes. Use Sentry's free tier (5K errors/month). You'll find bugs you never knew existed.
Sentry vs BetterStack?
Sentry for rich error context and performance. BetterStack for logs + basic errors. Sentry is the gold standard.
Should I track errors in development?
No. Set enabled: process.env.NODE_ENV === 'production' to avoid noise.
Bottom Line
Set up Sentry today. It takes 5 minutes and catches production errors you'd never find otherwise. Add user context, configure source maps, and set up Slack alerts. The free tier (5K errors/month) covers most small projects.