Custom Monitoring Provider
How to extend the repo's monitoring layer with your own provider.
Only Sentry is registered by default, but the monitoring layer is extensible. A complete provider must be registered in four places: the provider enum, the React provider component, the server service, and the instrumentation registries (client + server).
1. Add the Provider Name
Update the provider enum:
packages/monitoring/api/src/get-monitoring-provider.ts
const MONITORING_PROVIDERS = [ 'sentry', 'my-provider', '',] as const;2. Register the Client Provider Component
packages/monitoring/api/src/components/provider.tsx
monitoringProviderRegistry.register('my-provider', async () => { const { MyProvider } = await import('@kit/my-monitoring/provider'); return { default: function Wrapper({ children }: React.PropsWithChildren) { return <MyProvider>{children}</MyProvider>; }, };});3. Register the Server Service
packages/monitoring/api/src/services/get-server-monitoring-service.ts
serverMonitoringRegistry.register('my-provider', async () => { const { MyMonitoringService } = await import('@kit/my-monitoring'); return new MyMonitoringService();});4. Register Server Instrumentation
The server registration must export onRequestError. The client error.tsx relies on error.digest being set for any server-originated error so it can skip re-capturing — that dedup only works if every provider records server errors here, with the proper Next.js context (route, method, headers).
packages/monitoring/api/src/instrumentation.ts
instrumentationRegistry.register('my-provider', async () => { const { initMyProviderServer, captureMyProviderRequestError } = await import('@kit/my-monitoring/server'); return { register: () => { initMyProviderServer({ environment: process.env.NEXT_PUBLIC_MY_PROVIDER_ENVIRONMENT, }); }, onRequestError: captureMyProviderRequestError, };});5. Register Client Instrumentation
The client instrumentation owns the global window.onerror and unhandledrejection handlers. The provider must supply init and captureException; the buffer-then-replay machinery is handled for you.
packages/monitoring/api/src/instrumentation-client.ts
clientInstrumentationRegistry.register('my-provider', async () => { const { initMyProviderBrowser, captureMyProviderException } = await import('@kit/my-monitoring/client'); return { init: () => { initMyProviderBrowser({ environment: process.env.NEXT_PUBLIC_MY_PROVIDER_ENVIRONMENT, }); }, captureException: (error, mechanism) => { captureMyProviderException(error, { handled: false, type: mechanism }); }, };});Disable provider-owned global handlers
If your SDK installs its own window.onerror / unhandledrejection handlers (e.g. Sentry's GlobalHandlers integration), disable them in your init so they don't double-report alongside the kit's own handlers.
6. Configure the Environment
NEXT_PUBLIC_MONITORING_PROVIDER=my-providerNotes
- The repo is ESM. Use
import, notrequire. - All five registrations are required. If any is missing, the client/server experience will diverge or errors will silently drop.
- Leaving the env var empty keeps the console fallback.