npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@browsonic/nextjs

v1.3.0

Published

Next.js adapter for @browsonic/sdk — App Router error pages, route-handler capture, instrumentation entry. Re-exports @browsonic/react. Apache-2.0.

Readme

@browsonic/nextjs

Next.js adapter for @browsonic/sdk — App Router error-page components (with optional pathname / params context), route-handler capture wrapper, Pages Router companions (browsonicPagesAppInit / browsonicPagesErrorInitialProps), config wrapper, plus all the React-side primitives re-exported from @browsonic/react.

Status: App Router BrowsonicErrorPage / BrowsonicGlobalErrorPage accept optional pathname + params props that consumers thread from usePathname() / useParams() and land as the nextjs.pathname tag plus a params sub-key on the consolidated nextjs context bucket. Pages Router companions ship for pages/_app.tsx (browsonicPagesAppInit) and pages/_error.tsx (browsonicPagesErrorInitialProps). The instrumentation.ts helper (@browsonic/nextjs/instrumentation) ships. Build-time source-map upload is handled by @browsonic/build-tools — Next.js builds with Webpack, so drop its Webpack plugin into next.config (see next.config.js below); withBrowsonicConfig stays a forward-compat passthrough.

Why this adapter

Next.js's App Router has framework-specific error surfaces that the React adapter alone doesn't cover:

  1. app/error.tsx is rendered by Next.js when a route subtree throws. The component is a Client Component that receives { error, reset }. We ship a drop-in for it.
  2. app/global-error.tsx owns the <html> / <body> shell and is rendered when the root layout itself crashes. We ship a drop-in for it too.
  3. app/api/.../route.ts route handlers run server-side. A wrapper forwards thrown errors to the SDK (when reachable) before re-throwing them so Next.js can serve its 500.

This package depends on @browsonic/react and re-exports its surface so Next.js consumers install one package, not two.

Install

npm install @browsonic/sdk @browsonic/react @browsonic/nextjs

@browsonic/sdk, @browsonic/react, next (≥13.4), and react (18+) are all peer dependencies.

Quickstart — App Router error pages

// app/error.tsx
'use client';
import { BrowsonicErrorPage } from '@browsonic/nextjs';
export default BrowsonicErrorPage;
// app/global-error.tsx
'use client';
import { BrowsonicGlobalErrorPage } from '@browsonic/nextjs';
export default BrowsonicGlobalErrorPage;

The components capture { error, digest } to the SDK on mount, then render a minimal "Something went wrong" UI with a Try Again button. To customise, copy the 30-line implementation from src/error-page.tsx and adjust the JSX.

To attach route-context to captured errors, wrap the default export with pathname and params from Next's hooks:

// app/error.tsx
'use client';
import { usePathname, useParams } from 'next/navigation';
import { BrowsonicErrorPage } from '@browsonic/nextjs';

export default function ErrorPage(props: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return <BrowsonicErrorPage {...props} pathname={usePathname()} params={useParams()} />;
}

The boundary tags the captured event with nextjs.pathname and lands params as a sub-key on the single consolidated nextjs context bucket (alongside runtime / source / pathname) so dashboards can group errors by route shape.

Quickstart — Pages Router (Next ≤ 12 / opt-in 13+)

For projects on the Pages Router, two companions cover the equivalent surfaces:

// pages/_app.tsx
import type { AppProps } from 'next/app';
import { useEffect } from 'react';
import { browsonicPagesAppInit } from '@browsonic/nextjs';

export default function App({ Component, pageProps }: AppProps) {
  useEffect(() => browsonicPagesAppInit(), []);
  return <Component {...pageProps} />;
}
// pages/_error.tsx
import type { NextPage } from 'next';
import { browsonicPagesErrorInitialProps } from '@browsonic/nextjs';

interface ErrorProps {
  statusCode: number;
  pagePath?: string;
}

const Error: NextPage<ErrorProps> = ({ statusCode }) => <div>Error {statusCode}</div>;

// `browsonicPagesErrorInitialProps` IS the getInitialProps: it captures the
// error (browser-side only) and returns `{ statusCode, pagePath }` synchronously.
Error.getInitialProps = browsonicPagesErrorInitialProps;

export default Error;

browsonicPagesAppInit registers window-level error / unhandledrejection listeners on the client (call it from useEffect; it returns a teardown so the listeners are removed on unmount / fast refresh) and is a no-op on the server. browsonicPagesErrorInitialProps captures whatever Next put on ctx.err, sets the consolidated nextjs context bucket (runtime: 'browser', source: 'pages-router-error', plus statusCode / pagePath / asPath when present), tags nextjs.pagePath, and records nextjsStatusCode metadata — capture only fires browser-side (it no-ops during SSR).

Quickstart — Route handlers

// app/api/checkout/route.ts
import { withBrowsonicRouteHandler } from '@browsonic/nextjs';

export const POST = withBrowsonicRouteHandler(async (req: Request) => {
  const data = await req.json();
  if (!data.email) throw new Error('email required');
  return Response.json({ ok: true });
});

The wrapper forwards the thrown Error to sdk.captureError, tags it with nextjsRouteHandler: 'true', and re-throws — Next.js's normal 500 path is preserved.

Quickstart — instrumentation.ts (Next 13.4+)

Next.js's project-root instrumentation.ts file convention runs once at server startup (register()) and on every unhandled server error (onRequestError). The @browsonic/nextjs/instrumentation sub-entry ships a one-line wire-up:

// instrumentation.ts (project root, alongside `next.config.mjs`)
import { browsonicInstrumentation } from '@browsonic/nextjs/instrumentation';

const { register, onRequestError } = browsonicInstrumentation({
  apiEndpoint: process.env.BROWSONIC_API_ENDPOINT,
  appKey: process.env.BROWSONIC_APP_KEY,
  environment: process.env.VERCEL_ENV ?? process.env.NODE_ENV,
});

export { register, onRequestError };

What ships today:

  • register() validates that apiEndpoint + appKey are present and emits one console.warn per missing field. Misconfiguration surfaces at server boot instead of silently shipping pages with no telemetry.
  • onRequestError(error, request, context) forwards the error to console.error with a structured nextjs.* context object (nextjs.path, nextjs.routerKind, nextjs.routePath, nextjs.routeType, etc.). Tests / custom log sinks override the report path via the reportError option.

What ships later (without a code change in your instrumentation.ts):

  • Real server-runtime capture. The SDK is a browser library today, so onRequestError forwards to console.error rather than the ingest endpoint; a server-runtime transport is future work, independent of source maps (browser-side source-map upload already ships — see below).
  • BROWSONIC_INSTRUMENTATION_VERSION already tags emitted events so future dashboards can distinguish wire-up generations.

Server-only sub-entry — the main @browsonic/nextjs bundle has no server code.

Quickstart — next.config.js

// next.config.mjs
import { withBrowsonicConfig } from '@browsonic/nextjs';

export default withBrowsonicConfig({
  reactStrictMode: true,
  // your config
});

Today withBrowsonicConfig is a forward-compat passthrough — adopt it now to pick up future config-level integrations without editing this file again. It does not upload source maps.

Source-map upload

The source-map pipeline shipped in May 2026. Next.js builds with Webpack, so upload your production maps by adding the @browsonic/build-tools Webpack plugin to the Next config's webpack hook:

// next.config.mjs
import { BrowsonicSourceMapsPlugin } from '@browsonic/build-tools/webpack';

const nextConfig = {
  productionBrowserSourceMaps: true, // emit browser source maps at build time
  webpack(config, { isServer }) {
    if (!isServer) {
      config.devtool = 'hidden-source-map'; // write .map files without advertising them to users
      config.plugins.push(new BrowsonicSourceMapsPlugin({ appKey: 'web' }));
    }
    return config;
  },
};

export default nextConfig;

The release the plugin uploads under must match the SDK's clientVersion. See the @browsonic/build-tools README for the token, release, and env-var options.

Quickstart — Boundary inside Client Components

The full React surface re-exports through this package, so anywhere in your 'use client' tree you can:

'use client';
import { BrowsonicErrorBoundary, useUser } from '@browsonic/nextjs';

export function App() {
  useUser({ id: 'u1' });
  return (
    <BrowsonicErrorBoundary fallback={(error, reset) => <div>{error.message}</div>}>
      <Routes />
    </BrowsonicErrorBoundary>
  );
}

Naming note

withBrowsonic is the React HOC (re-exported from @browsonic/react). withBrowsonicConfig is the Next.js config wrapper (this package). The split mirrors @sentry/nextjs's withSentryConfig pattern.

Defensive contract

Same as every other adapter:

  • The host app must never crash because reporting failed.
  • SDK calls are wrapped in try { ... } catch {}.
  • All surfaces work without an SDK present (page still renders, route handler still throws upstream, config still passes through).

What this package does NOT do (yet)

  • Sourcemap upload through withBrowsonicConfig. Source-map upload itself ships today — wire the @browsonic/build-tools Webpack plugin into next.config (see above). withBrowsonicConfig stays a passthrough and does not upload maps.
  • Auto-detected instrumentation.ts injection. The shipped helper is opt-in (consumer pastes a 5-line wire-up). A build-time injector that creates the file automatically would need a transform on every project's root, which is more invasive than the consumer-opt-in convention.
  • Server-runtime capture. The SDK is a browser library; route-handler errors that occur in pure Node have no window to write to. The wrapper still re-throws so your handler returns its expected status.
  • Edge runtime instrumentation. Edge runtimes lack a stable global Browsonic singleton — adopt the SDK in the client layer and use the route-handler wrapper for opportunistic capture.
  • Pages Router data layer instrumentation (getServerSideProps / getStaticProps). Will be revisited only if Pages Router consumer demand surfaces.

License

Apache-2.0. See the repo root LICENSE and the package NOTICE.