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>