JavaScript SDK
The official JavaScript SDK for booboo.dev error tracking. Works in any browser environment with optional React and Vue integrations.
Installation
npm install @booboo.dev/js Quick start
import * as booboo from "@booboo.dev/js";
booboo.init({ dsn: "your-dsn-key" }); That's all you need. The SDK installs window.onerror and window.onunhandledrejection handlers to capture unhandled errors automatically.
API Reference
booboo.init(options)
Initialize booboo error tracking. Call this once when your application loads.
| Option | Type | Description |
|---|---|---|
dsn | string | Required. Your project's DSN key from the dashboard. |
environment | string | Free-form environment name (e.g. "development", "staging", "production"). Attached to every event for filtering in the dashboard. |
breadcrumbs | boolean | object | Configure breadcrumb collection. Defaults to true (all enabled). |
maxBreadcrumbs | number | Maximum breadcrumbs to keep. Defaults to 30. |
ignoreErrors | (string | RegExp)[] | Errors to suppress. Strings match error.name exactly; RegExps test against both error.name and error.message. |
captureHttpErrors | boolean | number[] | object | Auto-capture HTTP errors from fetch. true captures 5xx, array for specific status codes, or object with statuses and targets for URL filtering. |
beforeSend | function | Hook to modify or drop events before sending. Return null to drop. |
tags | object | Key-value pairs attached to every event. |
context | object | Additional context data attached to every event. |
Full example with all options:
booboo.init({
dsn: "your-dsn-key",
environment: "production",
tags: { version: "1.2.0" },
context: { userId: "user-123" },
breadcrumbs: {
console: true,
clicks: true,
navigation: true,
fetch: true,
},
maxBreadcrumbs: 30,
ignoreErrors: [
"ResizeObserver", // exact match on error.name
/Loading chunk \d+ failed/, // regex on name or message
],
captureHttpErrors: {
targets: [/api\.myapp\.com/],
},
beforeSend: (event) => {
// Return null to drop the event, or modify and return it
return event;
},
}); booboo.captureException(error, extra?)
Manually capture an error. Useful for errors you catch and handle gracefully.
try {
await riskyOperation();
} catch (err) {
booboo.captureException(err);
// handle gracefully
} booboo.captureMessage(message, level?)
Send a non-exception event. Level can be "error", "warning", or "info". Defaults to "info".
booboo.captureMessage("User hit rate limit", "warning"); booboo.setUser(user)
Set user context attached to every subsequent event. Pass null to clear.
| Parameter | Type | Description |
|---|---|---|
user | object | null | User data with keys like id, email, username. Pass null to clear. |
// Set user context — attached to every subsequent event
booboo.setUser({ id: "user-123", email: "alice@example.com" });
// Clear user context (e.g. on logout)
booboo.setUser(null); booboo.addBreadcrumb(crumb)
Add a custom breadcrumb to the trail.
booboo.addBreadcrumb({
type: "custom",
category: "auth",
message: "User logged in",
data: { method: "google" },
}); booboo.flush()
Returns a Promise that resolves when all queued events have been sent. Useful before page unload or process exit.
// Drain pending events before shutdown
await booboo.flush(); booboo.getClient()
Returns the global BoobooClient instance, or null if init() hasn't been called yet. Useful when you need direct access to the client in parts of your code that don't import the top-level module.
const client = booboo.getClient();
if (client) {
client.captureException(new Error("something broke"));
} axiosErrorInterceptor(options?)
Returns an Axios response error interceptor that captures HTTP errors. No Axios import required — just pass the return value to interceptors.response.use.
import axios from "axios";
import { axiosErrorInterceptor } from "@booboo.dev/js";
const api = axios.create({ baseURL: "/api" });
// Captures 5xx by default
api.interceptors.response.use(null, axiosErrorInterceptor());
// Or specify custom statuses
api.interceptors.response.use(null, axiosErrorInterceptor({ statuses: [429, 500] })); React Integration
ErrorBoundary
The ErrorBoundary component catches errors in your React component tree and sends them to booboo.dev. Import it from @booboo.dev/js/react.
import * as booboo from "@booboo.dev/js";
import { ErrorBoundary } from "@booboo.dev/js/react";
booboo.init({ dsn: "your-dsn-key" });
function App() {
return (
<ErrorBoundary
fallback={(error, reset) => (
<div>
<h2>Something went wrong</h2>
<pre>{error.message}</pre>
<button onClick={reset}>Try again</button>
</div>
)}
onError={(error, errorInfo) => {
console.log("Caught by boundary:", error);
}}
>
<MyApp />
</ErrorBoundary>
);
} | Prop | Type | Description |
|---|---|---|
fallback | ReactNode | function | UI to show when an error is caught. Function receives (error, reset). |
onError | function | Callback when an error is caught. Receives (error, errorInfo). |
React Query
Automatically capture errors from TanStack Query (React Query) queries and mutations. Query keys, hashes, and mutation IDs are included as context for easier debugging. Import boobooQueryIntegration from @booboo.dev/js/react and pass the config to your QueryClient.
import { QueryClient, QueryCache, MutationCache } from "@tanstack/react-query";
import { boobooQueryIntegration } from "@booboo.dev/js/react";
const b = boobooQueryIntegration();
const queryClient = new QueryClient({
queryCache: new QueryCache(b.queryCache),
mutationCache: new MutationCache(b.mutationCache),
}); Vue Integration
The BoobooVue plugin captures errors from Vue's app.config.errorHandler, including the component name and lifecycle info.
import * as booboo from "@booboo.dev/js";
import { BoobooVue } from "@booboo.dev/js/vue";
import { createApp } from "vue";
booboo.init({ dsn: "your-dsn-key" });
const app = createApp(App);
app.use(BoobooVue());
app.mount("#app"); Next.js
Since Next.js uses server-side rendering, initialize the SDK in a client component to ensure it only runs in the browser. Use a provider component in your root layout.
// app/providers.tsx
"use client";
import { useEffect } from "react";
import * as booboo from "@booboo.dev/js";
export function BoobooProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
booboo.init({ dsn: "your-dsn-key" });
}, []);
return <>{children}</>;
}
// app/layout.tsx
import { BoobooProvider } from "./providers";
export default function RootLayout({ children }) {
return (
<html>
<body>
<BoobooProvider>{children}</BoobooProvider>
</body>
</html>
);
} What gets captured
Each error event sent to booboo.dev includes:
- Exception type — the error constructor name (e.g.
TypeError) - Message — the error message string
- Stack trace — parsed frames with clean filenames, function, line, and column
- Source context — 5 lines of code above and below the error line (fetched from the dev server at runtime)
- App vs library frames — frames from
node_modules/are marked as library code and collapsed in the dashboard - Browser context — URL, user agent, screen size, viewport dimensions
- Breadcrumbs — trail of console logs, clicks, navigations, and fetch requests
- HTTP errors — automatic capture of 5xx (or custom) fetch responses when
captureHttpErrorsis enabled - Tags — custom key-value pairs plus the
runtime: "browser"tag - Environment — the environment set during
init()(e.g."production")
Breadcrumbs
Breadcrumbs provide a trail of events leading up to an error. The SDK automatically collects:
- Console —
console.log,warn,error,info, anddebugcalls - Clicks — user click events with element description
- Navigation —
pushState,replaceState, andpopstateevents - Fetch — HTTP requests with method, URL, status, and duration
You can disable specific collectors or all breadcrumbs:
// Disable fetch breadcrumbs only
booboo.init({ dsn: "...", breadcrumbs: { fetch: false } });
// Disable all breadcrumbs
booboo.init({ dsn: "...", breadcrumbs: false }); HTTP Error Capture
Enable captureHttpErrors to automatically capture HTTP errors from fetch() requests. By default this captures 5xx server errors, or you can specify exact status codes.
// Capture all 5xx fetch responses
booboo.init({
dsn: "your-dsn-key",
captureHttpErrors: true,
});
// Or specify exact status codes
booboo.init({
dsn: "your-dsn-key",
captureHttpErrors: [429, 500, 502, 503],
});
// Filter by URL to avoid noise from third-party services
booboo.init({
dsn: "your-dsn-key",
captureHttpErrors: {
targets: ["api.myapp.com", /^\/api\//],
},
});
// Combine specific statuses with URL filtering
booboo.init({
dsn: "your-dsn-key",
captureHttpErrors: {
statuses: [429, 500, 502, 503],
targets: ["api.myapp.com"],
},
});
For Axios, use the axiosErrorInterceptor helper — see the API Reference above.
beforeSend Hook
Use beforeSend to modify events before they're sent, or return null to drop them entirely.
booboo.init({
dsn: "your-dsn-key",
beforeSend: (event) => {
// Add custom tags
event.tags.page = window.location.pathname;
// Return null to drop the event entirely
return event;
},
});