Monitoring Next.js : Sentry, Vercel Analytics & Error Tracking 2026

Brandon Sueur16 min

Production without monitoring = flying blind. 78% bugs discovered by users, not teams.

Ce guide couvre monitoring complet Next.js : Sentry error tracking, Vercel Analytics, OpenTelemetry, performance monitoring, alerting et debugging production.

Résultat client : Mean Time To Resolution (MTTR) -73% (12h → 3h)

TL;DR : Stack Monitoring Next.js 2026

Tool Purpose Prix Setup Time Best For
Sentry Error tracking 0-26€/mois 15min 🏆 Errors & exceptions
Vercel Analytics Performance (Web Vitals) 10-150€/mois 5min Performance metrics
PostHog Product analytics 0-450€/mois 30min User behavior
LogRocket Session replay 99€+/mois 20min User sessions
Datadog Full observability 15€+/mois 2h Enterprise monitoring
OpenTelemetry Custom traces Gratuit 3-4h Advanced tracing

Recommendation Stack :

  • Sentry : Error tracking (must-have)
  • Vercel Analytics : Core Web Vitals (si Vercel hosting)
  • PostHog : Product analytics (optional)

1. Sentry — Error Tracking & Performance

Présentation

Prix 2026 :

  • Developer : Gratuit (5k errors/mois, 1 user)
  • Team : 26€/mois (50k errors/mois, 5 seats)
  • Business : 80€/mois (100k errors/mois, unlimited seats)

Features :

  • ✅ Error tracking (JavaScript, Server)
  • ✅ Performance monitoring (transactions, spans)
  • ✅ Source maps (production debugging)
  • ✅ Release tracking
  • ✅ User feedback
  • ✅ Alerting (Slack, Email, PagerDuty)

Setup Sentry Next.js 15

# Install Sentry SDK
pnpm add @sentry/nextjs
# Initialize (interactive wizard)
npx @sentry/wizard@latest -i nextjs

Configuration générée :

// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs'

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,

  // Tracing
  tracesSampleRate: 1.0, // 100% production (adjust based on traffic)

  // Session Replay
  replaysOnErrorSampleRate: 1.0, // Capture 100% sessions with errors
  replaysSessionSampleRate: 0.1, // Capture 10% normal sessions

  integrations: [
    Sentry.replayIntegration({
      maskAllText: true, // Privacy: mask sensitive text
      blockAllMedia: true, // Don't capture images/videos
    }),
  ],

  // Environment
  environment: process.env.NODE_ENV,

  // Release tracking
  release: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
})
// sentry.server.config.ts
import * as Sentry from '@sentry/nextjs'

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 1.0,
  environment: process.env.NODE_ENV,
})
// sentry.edge.config.ts
import * as Sentry from '@sentry/nextjs'

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 1.0,
})

Instrumentation :

// instrumentation.ts (Next.js 15 required)
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')
  }
}

Build configuration :

// next.config.ts
import { withSentryConfig } from '@sentry/nextjs'

const nextConfig = {
  // Your Next.js config
}

export default withSentryConfig(nextConfig, {
  org: 'your-org',
  project: 'your-project',

  // Upload source maps
  silent: !process.env.CI,
  widenClientFileUpload: true,

  // Route browser requests to Sentry through a Next.js rewrite
  tunnelRoute: '/monitoring',

  // Don't delete source maps (for debugging)
  hideSourceMaps: false,

  // Disable telemetry
  disableLogger: true,
})

Error Tracking Usage

Automatic error capture :

// app/page.tsx
export default function HomePage() {
  // Sentry automatically captures unhandled errors
  throw new Error('Test error') // ✅ Auto-captured
}

Manual error tracking :

import * as Sentry from '@sentry/nextjs'

try {
  await riskyOperation()
} catch (error) {
  Sentry.captureException(error, {
    level: 'error',
    tags: {
      section: 'checkout',
      user_action: 'payment',
    },
    extra: {
      paymentAmount: 99.99,
      currency: 'EUR',
    },
  })
}

Custom context :

// Set user context
Sentry.setUser({
  id: user.id,
  email: user.email,
  username: user.name,
})

// Set custom tags
Sentry.setTag('payment_provider', 'stripe')
Sentry.setTag('subscription_plan', 'pro')

// Add breadcrumbs (user actions)
Sentry.addBreadcrumb({
  category: 'navigation',
  message: 'User navigated to checkout',
  level: 'info',
})

Server Actions error tracking :

// app/actions/create-post.ts
'use server'

import * as Sentry from '@sentry/nextjs'
import { revalidatePath } from 'next/cache'

export async function createPost(formData: FormData) {
  try {
    const title = formData.get('title') as string

    await db.insert(posts).values({ title })
    revalidatePath('/blog')

    return { success: true }
  } catch (error) {
    Sentry.captureException(error, {
      tags: { action: 'create_post' },
      extra: { formData: Object.fromEntries(formData) },
    })

    return { error: 'Failed to create post' }
  }
}

Performance Monitoring

// Custom transaction
import * as Sentry from '@sentry/nextjs'

const transaction = Sentry.startTransaction({
  name: 'checkout-flow',
  op: 'checkout',
})

// Start span
const span = transaction.startChild({
  op: 'stripe-payment',
  description: 'Create Stripe payment intent',
})

try {
  await stripe.paymentIntents.create({ ... })
  span.setStatus('ok')
} catch (error) {
  span.setStatus('internal_error')
  throw error
} finally {
  span.finish()
  transaction.finish()
}

Automatic performance tracking :

// sentry.client.config.ts
Sentry.init({
  // ...
  integrations: [
    Sentry.browserTracingIntegration({
      tracePropagationTargets: ['localhost', /^https:\/\/yoursite\.com/],
    }),
  ],
})

Alerting (Slack Integration)

Sentry Dashboard :

  1. Settings > Integrations > Slack
  2. Connect workspace
  3. Configure alert rules

Alert rules example :

IF errors > 10 in 5 minutes
THEN notify #engineering-alerts channel

PagerDuty integration : For on-call critical alerts


2. Vercel Analytics — Web Vitals & Traffic

Présentation

Prix 2026 :

  • Hobby : Gratuit (2,500 events/mois)
  • Pro : Inclus Vercel Pro (100k events/mois)
  • Enterprise : Unlimited

Features :

  • ✅ Core Web Vitals (LCP, FID, CLS)
  • ✅ Real User Monitoring (RUM)
  • ✅ Traffic analytics
  • ✅ Audience insights (country, device)
  • ✅ Top pages

Setup Vercel Analytics

# Install
pnpm add @vercel/analytics
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="fr">
      <body>
        {children}
        <Analytics /> {/* ✅ Add analytics */}
      </body>
    </html>
  )
}

Web Vitals tracking :

// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        {children}
        <SpeedInsights /> {/* ✅ Core Web Vitals */}
      </body>
    </html>
  )
}

Custom events :

// components/buy-button.tsx
'use client'

import { track } from '@vercel/analytics'

export function BuyButton() {
  function handleClick() {
    track('purchase_initiated', {
      product: 'Pro Plan',
      price: 99,
    })
  }

  return <button onClick={handleClick}>Buy Now</button>
}

Vercel Web Analytics Dashboard

Metrics tracked :

  • LCP (Largest Contentful Paint)
  • FID (First Input Delay)
  • CLS (Cumulative Layout Shift)
  • TTFB (Time To First Byte)
  • FCP (First Contentful Paint)

Visualization :

  • Performance score (0-100)
  • Page-by-page breakdown
  • Device type comparison (desktop vs mobile)
  • Country breakdown

3. PostHog — Product Analytics

Présentation

Prix 2026 :

  • Gratuit : 1M events/mois
  • Paid : $0.00045/event (après free tier)

Features :

  • ✅ Product analytics (funnels, retention)
  • ✅ Session recordings
  • ✅ Feature flags
  • ✅ A/B testing
  • ✅ Heatmaps

Setup PostHog

pnpm add posthog-js
// app/providers.tsx
'use client'

import posthog from 'posthog-js'
import { PostHogProvider as PHProvider } from 'posthog-js/react'
import { useEffect } from 'react'

export function PostHogProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
      api_host: 'https://app.posthog.com',
      capture_pageview: false, // Disable auto pageview (we'll track manually)
    })
  }, [])

  return <PHProvider client={posthog}>{children}</PHProvider>
}

Track events :

// components/signup-form.tsx
'use client'

import { usePostHog } from 'posthog-js/react'

export function SignupForm() {
  const posthog = usePostHog()

  function handleSignup() {
    posthog.capture('user_signed_up', {
      plan: 'pro',
      source: 'landing_page',
    })
  }

  return <form onSubmit={handleSignup}>...</form>
}

4. Source Maps (Production Debugging)

Problem

Production :

Error at build/chunks/app.js:1:45821

Can't debug! Code minified/obfuscated.

Solution : Source Maps

Sentry automatic source maps upload :

// next.config.ts
export default withSentryConfig(nextConfig, {
  widenClientFileUpload: true, // ✅ Upload source maps
  hideSourceMaps: false, // Keep source maps in build
})

Manual upload (if needed) :

# Sentry CLI
sentry-cli sourcemaps upload \
  --org your-org \
  --project your-project \
  --release $RELEASE \
  .next/static/chunks

Result : Stack traces show original source code in Sentry


5. Logging (Structured Logs)

Pino Logger (Fast & Structured)

pnpm add pino pino-pretty
// lib/logger.ts
import pino from 'pino'

export const logger = pino({
  level: process.env.LOG_LEVEL || 'info',
  ...(process.env.NODE_ENV === 'development' && {
    transport: {
      target: 'pino-pretty',
      options: {
        colorize: true,
      },
    },
  }),
})

Usage :

// app/api/users/route.ts
import { logger } from '@/lib/logger'

export async function GET(req: Request) {
  logger.info({ path: req.url }, 'Fetching users')

  try {
    const users = await db.query.users.findMany()
    logger.info({ count: users.length }, 'Users fetched')

    return Response.json(users)
  } catch (error) {
    logger.error({ error }, 'Failed to fetch users')
    throw error
  }
}

Ship logs to external service :

// lib/logger.ts (production)
import pino from 'pino'

export const logger = pino({
  level: 'info',
  ...(process.env.NODE_ENV === 'production' && {
    transport: {
      target: 'pino-logflare', // LogFlare sink
      options: {
        apiKey: process.env.LOGFLARE_API_KEY,
        sourceToken: process.env.LOGFLARE_SOURCE_TOKEN,
      },
    },
  }),
})

Alternatives :

  • Axiom (Vercel integration)
  • Datadog Logs
  • CloudWatch (AWS)

6. Uptime Monitoring

BetterStack (formerly Better Uptime)

Prix : 25€/mois (10 monitors)

Features :

  • ✅ HTTP/HTTPS monitoring
  • ✅ SSL certificate expiry alerts
  • ✅ Multi-region checks (15 locations)
  • ✅ Incident management
  • ✅ Status page

Setup :

  1. Add monitor URL (https://yoursite.com)
  2. Configure check interval (30s-5min)
  3. Set alert channels (Slack, SMS, Call)

Alternative : UptimeRobot (gratuit, 50 monitors)


7. Real User Monitoring (RUM)

Performance Observer API

// lib/rum.ts
'use client'

import { useEffect } from 'react'

export function useRUM() {
  useEffect(() => {
    // Core Web Vitals
    if (typeof window !== 'undefined' && 'PerformanceObserver' in window) {
      const observer = new PerformanceObserver((list) => {
        list.getEntries().forEach((entry) => {
          if (entry.entryType === 'largest-contentful-paint') {
            console.log('LCP:', entry.startTime)
            // Send to analytics
            fetch('/api/analytics', {
              method: 'POST',
              body: JSON.stringify({
                metric: 'LCP',
                value: entry.startTime,
              }),
            })
          }
        })
      })

      observer.observe({ entryTypes: ['largest-contentful-paint'] })

      return () => observer.disconnect()
    }
  }, [])
}

8. Error Boundaries (React)

// app/error.tsx
'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 className="flex min-h-screen items-center justify-center">
      <div className="text-center">
        <h2 className="text-2xl font-bold">Something went wrong!</h2>
        <button onClick={reset} className="mt-4 rounded bg-blue-600 px-4 py-2 text-white">
          Try again
        </button>
      </div>
    </div>
  )
}

Global error (app-level) :

// app/global-error.tsx
'use client'

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

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

  return (
    <html>
      <body>
        <h2>Application Error</h2>
      </body>
    </html>
  )
}

9. Monitoring Checklist Production

Pre-Launch

  • Sentry configured (client + server + edge)
  • Source maps uploaded
  • Vercel Analytics enabled
  • Error boundaries implemented
  • Alerting configured (Slack/Email)
  • Uptime monitor setup (BetterStack/UptimeRobot)
  • Logging structured (Pino)
  • Performance budget defined (Core Web Vitals thresholds)

Post-Launch

  • Monitor error rate daily (Sentry dashboard)
  • Track Core Web Vitals weekly (Vercel Analytics)
  • Review logs for anomalies (Axiom/Datadog)
  • Check uptime SLA (99.9%+ target)
  • Analyze user journeys (PostHog funnels)
  • Review slow API routes (Sentry performance)

10. Cost Comparison

Monitoring Stack Costs (50k users/mois)

Tool Plan Prix/mois
Sentry Team 26€
Vercel Analytics Pro (included) 0€
PostHog Cloud 50€
BetterStack Starter 25€
Axiom Logs Pro 25€
Total 126€/mois

ROI :

  • MTTR -73% (12h → 3h)
  • Prevented downtime : ~4h/mois saved
  • Downtime cost (SaaS) : ~3,000€/h
  • Savings : 12,000€/mois (vs 126€ cost)

ROI ratio : 95× return


Conclusion

Monitoring Next.js = non-négociable production.

Stack recommandé 2026 :

  1. Sentry : Error tracking (26€/mois)
  2. Vercel Analytics : Core Web Vitals (gratuit Vercel Pro)
  3. BetterStack : Uptime (25€/mois)

Total : 51€/mois pour monitoring complet

Alternative budget serré :

  • Sentry Developer (gratuit)
  • UptimeRobot (gratuit)
  • Vercel Analytics (gratuit Hobby)

Total : 0€/mois (limites strictes)


FAQ

Sentry gratuit production-ready ?

⚠️ Non. Developer plan = 5k errors/mois. Production business dépasse rapidement. Team minimum (26€) recommandé.

Vercel Analytics vs Google Analytics ?

Vercel : Performance (Core Web Vitals). Google : Marketing (acquisition, conversions). Complémentaires, pas alternatives.

Sentry impact performance ?

Négligeable si configured correctement. tracesSampleRate: 0.1 (sample 10% traffic) recommandé high-traffic apps.


Articles connexes :