docs
Dashboard

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.

OptionTypeDescription
dsnstringRequired. Your project's DSN key from the dashboard.
environmentstringFree-form environment name (e.g. "development", "staging", "production"). Attached to every event for filtering in the dashboard.
breadcrumbsboolean | objectConfigure breadcrumb collection. Defaults to true (all enabled).
maxBreadcrumbsnumberMaximum breadcrumbs to keep. Defaults to 30.
beforeSendfunctionHook to modify or drop events before sending. Return null to drop.
tagsobjectKey-value pairs attached to every event.
contextobjectAdditional 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,
  beforeSend: (event) => {
    // Return null to drop the event
    if (event.message.includes("ResizeObserver")) return null;
    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".

booboo.captureMessage("User hit rate limit", "warning");

booboo.addBreadcrumb(crumb)

Add a custom breadcrumb to the trail.

booboo.addBreadcrumb({
  type: "custom",
  category: "auth",
  message: "User logged in",
  data: { method: "google" },
});

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"));
}

React Integration

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>
  );
}
PropTypeDescription
fallbackReactNode | functionUI to show when an error is caught. Function receives (error, reset).
onErrorfunctionCallback when an error is caught. Receives (error, errorInfo).

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>
  );
}
Note: The JavaScript SDK only captures client-side errors. Server-side errors in Next.js API routes or server components should use the Python SDK or a future Node.js integration.

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
  • Tags — custom key-value pairs plus the runtime: "browser" tag
  • Environment — the environment set during init() (e.g. "production")

Breadcrumbs provide a trail of events leading up to an error. The SDK automatically collects:

  • Consoleconsole.log, warn, error, info, and debug calls
  • Clicks — user click events with element description
  • NavigationpushState, replaceState, and popstate events
  • 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 });

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) => {
    // Drop noisy browser errors
    if (event.message.includes("ResizeObserver")) return null;

    // Add custom tags
    event.tags.page = window.location.pathname;

    return event;
  },
});