Sign Up
Open in ChatGPT Open in Claude Open in Perplexity

React / Next.js Integration

The Monoscope Browser SDK provides a @monoscopetech/browser/react subpath export with idiomatic React bindings — context providers, hooks, and an error boundary.

Install via Claude Code

Use Claude Code? Our skill will instrument this project for you. Add the marketplace, install the skill, and install our CLI:

claude plugin marketplace add monoscope-tech/skills
claude plugin install monoscope-skills@monoscope-skills
curl monoscope.tech/install.sh | sh
monoscope auth login

Then run inside Claude Code:

/monoscope-skills:instrument OpenTelemetry via Monoscope into this project

The skill drives the CLI to wire up the SDK and verify it. Prefer a human? Email us — happy to jump on a call or connect over Slack.

Installation

npm install @monoscopetech/browser

Quick Start

Wrap your app with MonoscopeProvider and use hooks to access the SDK:

import { MonoscopeProvider, useMonoscope, useMonoscopeUser, MonoscopeErrorBoundary } from "@monoscopetech/browser/react";

function App() {
  return (
    <MonoscopeProvider config={{ apiKey: "YOUR_API_KEY" }}>
      <MonoscopeErrorBoundary fallback={<div>Something went wrong</div>}>
        <MyApp />
      </MonoscopeErrorBoundary>
    </MonoscopeProvider>
  );
}

function MyApp() {
  const monoscope = useMonoscope();
  useMonoscopeUser(currentUser ? { id: currentUser.id, email: currentUser.email } : null);
  return <div>...</div>;
}

Next.js App Router

The provider includes "use client" — import it in a client component or your root layout:

// app/providers.tsx
"use client";

import { MonoscopeProvider, MonoscopeErrorBoundary } from "@monoscopetech/browser/react";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <MonoscopeProvider config={{ apiKey: "YOUR_API_KEY" }}>
      <MonoscopeErrorBoundary fallback={<div>Something went wrong</div>}>
        {children}
      </MonoscopeErrorBoundary>
    </MonoscopeProvider>
  );
}
// app/layout.tsx
import { Providers } from "./providers";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

React API

Export Description
MonoscopeProvider Context provider. Creates and destroys the SDK instance. Strict Mode safe.
useMonoscope() Returns the Monoscope instance (or null during SSR).
useMonoscopeUser(user) Calls setUser reactively when the user object changes.
MonoscopeErrorBoundary Error boundary that reports caught errors to Monoscope. Accepts fallback prop.

Custom Spans in Components

Use the useMonoscope() hook to create custom spans from any component:

import { useMonoscope } from "@monoscopetech/browser/react";

function CheckoutButton() {
  const monoscope = useMonoscope();

  const handleClick = () => {
    monoscope?.startSpan("checkout.submit", async (span) => {
      span.setAttribute("cart.items", cartItems.length);
      await submitOrder();
    });
  };

  return <button onClick={handleClick}>Checkout</button>;
}

Tracking Events

function SearchBar() {
  const monoscope = useMonoscope();

  const handleSearch = (query: string) => {
    monoscope?.recordEvent("search", {
      "search.query": query,
      "search.source": "header",
    });
    performSearch(query);
  };

  return <input onChange={(e) => handleSearch(e.target.value)} />;
}

Instrumenting Data Fetching

function Dashboard({ id }: { id: string }) {
  const monoscope = useMonoscope();
  const [data, setData] = useState(null);

  useEffect(() => {
    monoscope?.startSpan("dashboard.load", async (span) => {
      span.setAttribute("dashboard.id", id);
      const res = await fetch(`/api/dashboards/${id}`);
      span.setAttribute("http.status", res.status);
      setData(await res.json());
    });
  }, [id]);

  return data ? <DashboardView data={data} /> : <Loading />;
}

Configuration

MonoscopeProvider accepts the same configuration as the base SDK. See the Browser SDK configuration for the full list of options.

<MonoscopeProvider
  config={{
    apiKey: "YOUR_API_KEY",
    serviceName: "my-react-app",
    enableUserInteraction: true,
    sampleRate: 0.5,
    debug: process.env.NODE_ENV === "development",
  }}
>
  {children}
</MonoscopeProvider>