Overview

Get started with browser extension monitoring in TurboStarter.

TurboStarter includes powerful, provider-agnostic monitoring helpers for the browser extension so you can understand what failed, where it failed (popup, content script, background), and who it impacted. The API is intentionally designed for simplicity and extensibility, so you can swap providers without rewriting your extension code.

Capturing exceptions

Extensions have multiple runtimes. To get good coverage, capture errors in the places users actually feel them:

  • Popup / options UI: React pages where runtime errors break interactions.
  • Background (service worker): long-lived logic like alarms, message routing, and sync.
  • Content scripts: page integrations where DOM differences and CSP can trigger failures.
  • Manual reporting: wrap critical flows (auth, billing, webhooks-to-extension sync, imports) with try/catch and report with context.
import { captureException } from "@workspace/monitoring-extension";

export function ExampleButton() {
  const onPress = async () => {
    try {
      /* some risky operation */
    } catch (error) {
      captureException(error);
    }
  };

  return <button onClick={onPress}>Trigger Exception</button>;
}

Don't rely on a single runtime

An exception in a content script won't automatically show up in your background logs (and vice versa). Add capture points in each runtime you ship, especially if you do message passing between them.

Identifying users

Monitoring becomes far more useful once reports can be tied to a stable identity. In extensions you often have two “identities”:

  • Anonymous, stable install id: useful before sign-in (and to correlate issues with a device/install).
  • Signed-in user: once the user authenticates, identify with their user id so issues map to a real account.

TurboStarter's monitoring layer supports identifying the current user when your auth session resolves. When signed out, pass null (or your provider's preferred anonymous identity strategy).

monitoring.tsx
import { useEffect } from "react";
import { identify } from "@workspace/monitoring-extension";
import { authClient } from "~/lib/auth/client";

export const MonitoringProvider = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const session = authClient.useSession();

  useEffect(() => {
    if (session.isPending) {
      return;
    }

    identify(session.data?.user ?? null);
  }, [session]);

  return <>{children}</>;
};

Privacy defaults

Prefer stable IDs over PII. Only attach traits that help debugging (plan, role, extension version) and avoid secrets (tokens, passwords) or sensitive fields unless you've explicitly chosen to send them.

Providers

The starter supports multiple monitoring providers behind the same API, so you can start with one and switch later.

Best practices

Include runtime + version context

Extension issues are often environment-specific. Make sure you can filter by runtime (popup/background/content script), extension version, and browser.

Capture actionable failures

Focus on crashes and failures that break core flows; skip “expected” states like validation errors or user cancellations.

Dedupe noisy loops

Background alarms, retries, and message loops can generate many identical errors. Guard your capture calls to keep signal high (and costs low).

Keep environments separate

Don't mix dev/beta/stable releases. Tag builds so you can correlate spikes with a rollout and verify fixes quickly.

With capture points in each runtime, user identification wired up, and a provider configured, extension monitoring becomes a tight feedback loop: you can spot regressions early, understand which surface area is failing and validate fixes confidently as you ship new versions.

How is this guide?

Last updated on

On this page

Ship your startup everywhere. In minutes.Get TurboStarter