Skip to Content
FeaturesModulesMonitorFrontend SDK

Frontend SDK — @djangocfg/monitor

@djangocfg/monitor is the JavaScript counterpart to django_monitor. Browser and server events go to POST /cfg/monitor/ingest/ and land in D1 as frontend_events.


Package Structure

@djangocfg/monitor — types only, server-safe @djangocfg/monitor/client — browser SDK ("use client") @djangocfg/monitor/server — Node.js / Edge Runtime

Install

pnpm add @djangocfg/monitor

Optional peer dependencies:

PackagePurpose
consolaconsola reporter instead of console.* patch
zustandrequired for the client entry point event buffer

If your app uses @djangocfg/layouts, you get monitor for free — no MonitorProvider needed.

// app/[locale]/layout.tsx import { BaseApp } from '@djangocfg/layouts' export default function RootLayout({ children }) { return ( <html lang="en" suppressHydrationWarning> <body> <BaseApp project="my-app" auth={{ apiUrl: process.env.NEXT_PUBLIC_API_URL }} theme={{ defaultTheme: 'dark' }} // monitor is auto-enabled via `project` prop > {children} </BaseApp> </body> </html> ) }

BaseApp includes MonitorProvider automatically. The project prop is passed through to monitor as-is.

To override monitor defaults:

<BaseApp project="my-app" monitor={{ baseUrl: 'https://api.example.com', captureConsole: false }} >

How it connects


Standalone MonitorProvider

Without @djangocfg/layouts, drop it directly into your root layout:

import { MonitorProvider } from '@djangocfg/monitor/client' export default function RootLayout({ children }) { return ( <html> <body> <MonitorProvider project="my-app" environment={process.env.NODE_ENV} // baseUrl defaults to same origin /> {children} </body> </html> ) }

Auto-captured after init:

SourceMechanism
JS exceptionswindow.onerror + unhandledrejection
Console warnings/errorsconsola reporter or console.* patch
@djangocfg/api Zod failureszod-validation-error CustomEvent

Independent of console verbosity. @djangocfg/* packages gate the browser console by role (applyRoleLogPolicy from @djangocfg/api — quiet for regular users in production, verbose for admins/dev). Monitor capture is unaffected: errors are still captured and sent to the backend even when the console is silenced, so production incidents stay diagnosable.


Network Monitoring

import { monitoredFetch } from '@djangocfg/monitor/client' const res = await monitoredFetch('/api/orders', { method: 'POST', body: JSON.stringify(order) }) // non-2xx responses → captured as NETWORK_ERROR event

Manual Capture (client)

import { FrontendMonitor } from '@djangocfg/monitor/client' import { EventType, EventLevel } from '@djangocfg/monitor' FrontendMonitor.capture({ event_type: EventType.JS_ERROR, level: EventLevel.ERROR, message: 'Payment failed', url: window.location.href, extra: { orderId: '123' }, })

window.monitor — DevTools API

After MonitorProvider mounts, window.monitor is available in the browser console:

// Fire events manually window.monitor.error('Something broke', { context: 'checkout' }) window.monitor.warn('Slow response', { ms: 2500 }) window.monitor.info('User action', { action: 'checkout' }) window.monitor.network(404, 'GET', '/api/users/') window.monitor.network(502, 'POST', '/api/orders/', { retries: 3 }) // Force-flush buffered events window.monitor.flush() // Inspect current state (config, buffer size, session_id) window.monitor.status()

Server Usage (Next.js Route Handlers)

Configure once

// lib/monitor.ts import { serverMonitor } from '@djangocfg/monitor/server' serverMonitor.configure({ project: process.env.PROJECT_NAME ?? 'my-app', environment: process.env.NODE_ENV, baseUrl: 'https://api.myapp.com', // required if backend is on a different origin }) export { serverMonitor }

Route handler — manual

// app/api/orders/route.ts import { serverMonitor } from '@/lib/monitor' export async function POST(req: Request) { try { // ... } catch (err) { await serverMonitor.captureError(err, { url: req.url }) return new Response('Internal Server Error', { status: 500 }) } }

Route handler — withMonitor HOC

import { withMonitor } from '@djangocfg/nextjs/monitor' export const POST = withMonitor(async (req) => { // errors captured automatically — no try/catch needed })

Debug Panel Integration (@djangocfg/debuger)

Install @djangocfg/debuger alongside @djangocfg/monitor:

pnpm add @djangocfg/debuger

The monitor auto-bridges its event store into the debug panel’s Logs tab — no extra setup. Monitor events appear as monitor:JS_ERROR, monitor:NETWORK_ERROR, etc.

Open the panel with Cmd+D or add ?debug=1 to the URL.

When using @djangocfg/layouts, the debug panel is already included — just add @djangocfg/debuger as a dependency.


Client Configuration Reference

OptionTypeDefaultDescription
projectstring''Project name sent with every event
environmentstring''production / staging / development
baseUrlstringsame originBase URL of the django-cfg backend
flushIntervalnumber5000Buffer flush interval (ms)
maxBufferSizenumber20Max events before immediate flush
captureJsErrorsbooleantruewindow.onerror + unhandled rejections
captureConsolebooleantrueconsole.warn / console.error interception
debugbooleanfalseLog init info to console

Transport

Events are batched and flushed via the generated API client:

  • Normal flushmonitorApi.monitor.ingestCreate(batch) (standard fetch)
  • Page unloadKeepAliveFetchAdapter with keepalive: true — ensures delivery after navigation

Transport errors are always swallowed — monitor never crashes your app.


Ingest Endpoint

POST /cfg/monitor/ingest/ Content-Type: application/json
ParameterValue
AuthenticationNot required
Max batch size50 events
Success response202 Accepted

See Also

TAGS: django_monitor, frontend-sdk, javascript, next.js, layouts, debuger DEPENDS_ON: [django-monitor/overview]

Last updated on