Monitoring Overview

Current monitoring behavior in the Next.js Drizzle SaaS Kit.

The monitoring layer in this repo is extensible, but the checked-in runtime currently supports one built-in provider: Sentry.

Current State

  • @kit/monitoring-core provides the base service types and console fallback
  • @kit/monitoring provides provider selection, hooks, server helpers, and the instrumentation entrypoints
  • @kit/sentry is the only registered concrete provider in the repo
  • If NEXT_PUBLIC_MONITORING_PROVIDER is unset, the app falls back to console logging

Architecture

Errors enter monitoring through three paths, each provider-agnostic:

  • apps/web/instrumentation.ts — calls registerMonitoringInstrumentation() on boot, then forwards onRequestError to the configured provider. Server errors from RSC, Server Actions, and Route Handlers are captured here, with Next.js context (route, method, headers).
  • apps/web/instrumentation-client.ts — calls registerClientMonitoringInstrumentation(), which installs the kit's own window.onerror and unhandledrejection handlers, lazily loads the provider chunk in parallel with hydration, and buffers any errors that fire before init resolves.
  • useCaptureException / useMonitoring / getServerMonitoringService — manual capture from your code (see Capturing Errors).

Dedup invariant

Next.js attaches error.digest only to errors that originated server-side. The kit's error.tsx skips capture when a digest is present, on the assumption that the configured provider's onRequestError already recorded it. Custom providers must honor this contract.

Capturing outside the provider tree

global-error.tsx replaces the root layout, so the React MonitoringContext isn't available. Use captureClientException from @kit/monitoring/instrumentation-client in that shell.

Supported Provider Values

Current runtime support:

  • sentry
  • empty / unset value for console fallback

Other provider names are not registered by default in this repository.

Quick Start

apps/web/.env.local

NEXT_PUBLIC_MONITORING_PROVIDER=sentry
NEXT_PUBLIC_SENTRY_DSN=https://xxxxx@xxxxx.ingest.sentry.io/xxxxx

Manual Capture

Client-side:

import { useMonitoring } from '@kit/monitoring/hooks';
function MyComponent() {
const monitoring = useMonitoring();
async function onSubmit() {
try {
await submitForm();
} catch (error) {
monitoring.captureException(error as Error, {
context: 'form_submission',
});
}
}
}

Server-side:

import { getServerMonitoringService } from '@kit/monitoring/server';
export async function processPayment() {
const monitoring = await getServerMonitoringService();
try {
// ...
} catch (error) {
await monitoring.captureException(error as Error);
throw error;
}
}

Extending Monitoring

You can add more providers, but they are not prewired in this repo. A new provider requires registration in the client provider component, the server service, and both instrumentation registries (client + server). See Custom Monitoring Provider for the full pattern.

Topics

  1. Sentry
  2. Custom Monitoring Provider
  3. Capturing Errors