Naijacloud
Docs

Next.js

Two files, one import. The same @naijacloud/argus/next import picks the server build in one and the browser build in the other.

4 min read

Install

Install
bash
npm install @naijacloud/argus

Set up

Add two files at the root of your app (next to app/, or inside src/ if you use one):

ts
import { init } from '@naijacloud/argus/next' export const register = () => init({ dsn: 'https://<public key>@argus-in.naijacloud.com/<project id>' })

On Next.js 15 and later, also export the request-error hook from instrumentation.ts, so errors in route handlers, server actions and rendering are reported:

instrumentation.ts
ts
export { onRequestError } from '@naijacloud/argus/next'

The DSN's key is public, so it's safe in the browser file. To keep it out of your code, read it from the environment: process.env.ARGUS_DSN on the server and process.env.NEXT_PUBLIC_ARGUS_DSN in the browser. On the server, init() with no dsn reads ARGUS_DSN, then SENTRY_DSN, which a Naijacloud service gets from its Send errors to Argus switch.

Send a test event

Send a test event
bash
npx @naijacloud/argus test --dsn https://<public key>@argus-in.naijacloud.com/<project id>

It sends one test event and says whether Argus accepted it. Without --dsn it uses ARGUS_DSN.

What it captures

  • On the server (the Node.js runtime): uncaught exceptions and unhandled rejections, every incoming request traced, outgoing fetch() calls as spans, and with onRequestError, errors from route handlers, server actions and rendering, named after the route.
  • In the browser: uncaught errors and promise rejections, with breadcrumbs of clicks (which element, never what was typed), navigation, console, fetch and XHR. Errors raised offline are kept and sent when the browser is back online.
  • In the Edge runtime, init() does nothing. Middleware and edge routes are not reported.

Report errors yourself

Errors
ts
import { captureException, setUser } from '@naijacloud/argus/next' setUser({ id: session.userId }) try { await chargeCard(order) } catch (err) { captureException(err, { tags: { provider: 'paystack' } }) }

Logs, metrics and traces

app/api/pay/route.ts
ts
import { log, metrics, trace } from '@naijacloud/argus/next' export async function POST(req: Request) { const order = await req.json() log.info('payment started', { orderId: order.id }) metrics.count('payments.started', 1, { method: 'card' }) await trace('charge card', async (span) => { span?.setAttribute('provider', 'paystack') await paystack.charge(order) }) return Response.json({ ok: true }) }

Logs are sent every 5 seconds and metrics every 10. More in Node.js.

Cron check-ins and feature flags

Cron check-ins and feature flags
ts
import { cron, flags } from '@naijacloud/argus/next' // Create the monitor in Argus first. await cron.withMonitor('nightly-invoices', () => sendInvoices()) if (await flags.isOn('new-checkout', user.id)) { // … }

withMonitor reports the start, then success or failure. A flag check returns your fallback (false here) if Argus can't be reached. Answers are cached for 30 seconds per user.

Release and environment

On the server, the SDK reads ARGUS_RELEASE and ARGUS_ENVIRONMENT, then SENTRY_RELEASE and SENTRY_ENVIRONMENT. The browser can't read those, so pass them in instrumentation-client.ts, from variables set at build time:

instrumentation-client.ts
ts
init({ dsn: process.env.NEXT_PUBLIC_ARGUS_DSN, release: process.env.NEXT_PUBLIC_RELEASE, environment: 'production', })

The environment is production when none is set.

Privacy

On by default, in both files:

  • Values of keys such as password, token, secret, authorization, cookie, bvn and card become [Filtered], at any depth.
  • Card numbers, bearer tokens and JWTs are filtered inside strings.
  • Query strings are removed from URLs in breadcrumbs and spans.
  • Clicks record the element, never what was typed.
  • The user's IP address is not sent unless you set sendDefaultPii: true.

Pass beforeSend to init() to change an event, or return null to drop it:

beforeSend
ts
init({ beforeSend: (event) => event.exception?.values.at(-1)?.value.includes('ResizeObserver') ? null : event, })

Already on Sentry

Keep @sentry/nextjs. In sentry.server.config.ts and sentry.client.config.ts, change the dsn line:

sentry.server.config.ts
ts
dsn: 'https://<public key>@argus-in.naijacloud.com/<project id>',

Source maps

Browser stack traces point at minified bundles until you upload your build's source maps. Set productionBrowserSourceMaps: true in next.config, pass the same release to the SDK and to the upload, and follow Source maps.