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.
ignoreErrors(string | RegExp)[]Errors to suppress. Strings match error.name exactly; RegExps test against both error.name and error.message.
captureHttpErrorsboolean | number[] | objectAuto-capture HTTP errors from fetch. true captures 5xx, array for specific status codes, or object with statuses and targets for URL filtering.
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,
  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.

ParameterTypeDescription
userobject | nullUser 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>
  );
}
PropTypeDescription
fallbackReactNode | functionUI to show when an error is caught. Function receives (error, reset).
onErrorfunctionCallback 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>
  );
}
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
  • HTTP errors — automatic capture of 5xx (or custom) fetch responses when captureHttpErrors is enabled
  • 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 });

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