> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squasher.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Browser SDK

> Capture browser errors, Core Web Vitals, navigation events, and optional session replay from a web app.

`@squasher-ai/browser` is the browser-native SDK for Squasher. It captures frontend errors, Core Web Vitals, page context, analytics-style events, and optional session replay without pulling Node-only code into your bundle.

## Installation

```bash theme={null}
npm install @squasher-ai/browser
```

## Setup

Initialize the SDK once when your app boots:

```typescript src/main.ts theme={null}
import { init } from "@squasher-ai/browser";

init({
  apiKey: process.env.NEXT_PUBLIC_SQUASHER_API_KEY!,
  projectId: process.env.NEXT_PUBLIC_SQUASHER_PROJECT_ID!,
  environment: process.env.NODE_ENV,
  release: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
});
```

Errors, Web Vitals, and session replay all start automatically — no extra configuration needed.

To also send `console.error(...)` calls as error events, enable console error capture:

```typescript theme={null}
init({
  apiKey: process.env.NEXT_PUBLIC_SQUASHER_API_KEY!,
  projectId: process.env.NEXT_PUBLIC_SQUASHER_PROJECT_ID!,
  captureConsoleErrors: true,
});
```

## Use a standalone client

`init()` sets the optional page-wide client used by the package-level helpers. Use `BrowserClient`
directly when a component, micro-frontend, or test must own its SDK lifecycle:

```typescript theme={null}
import { BrowserClient } from "@squasher-ai/browser";

const client = new BrowserClient({
  apiKey: import.meta.env.PUBLIC_SQUASHER_API_KEY,
  projectId: import.meta.env.PUBLIC_SQUASHER_PROJECT_ID,
  environment: import.meta.env.MODE,
});

client.captureMessage("Checkout mounted", "info");

// Remove handlers, stop collectors, and flush buffered browser telemetry.
client.close();
```

Methods on `BrowserClient` do not use the page-wide client. Package-level helpers such as
`captureError()` and `close()` continue to use the client created by `init()`. Each standalone
client installs the automatic capture and replay features in its configuration, so disable features
that another client already owns.

## Automatic Capture

Once initialized, the browser SDK captures:

* uncaught errors from `window.onerror`
* unhandled promise rejections
* Core Web Vitals: `LCP`, `CLS`, `INP`, `FCP`, and `TTFB`
* automatic breadcrumbs for navigation, clicks, and failed fetches
* console warnings and errors as breadcrumbs
* a session identifier to correlate frontend errors, vitals, and replay data

Set `captureConsoleErrors: true` when you want `console.error(...)` calls to create their own error events, even if no exception is thrown.

## Manual Capture

Use the helpers when you want to record explicit product or agent telemetry from the browser:

```typescript theme={null}
import {
  addBreadcrumb,
  captureError,
  captureGeneration,
  captureMessage,
  identify,
  page,
  setTag,
  track,
} from "@squasher-ai/browser";

identify("user_42", {
  plan: "pro",
  workspaceId: "ws_123",
});

setTag("region", "us-east-1");
addBreadcrumb({ category: "checkout", message: "Opened payment modal" });

track("checkout_started", { step: 1 });
page("Checkout", { source: "pricing_page" });
captureMessage("Frontend boot complete", "info");
captureGeneration("Suggested reply rendered", {
  llm: {
    provider: "openai",
    model: "gpt-4o-mini",
    prompt_tokens: 420,
    completion_tokens: 90,
    total_tokens: 510,
    cached_input_tokens: 200,
  },
});

try {
  await submitCheckout();
} catch (error) {
  captureError(error as Error, { cartId: "cart_123" });
}
```

## Next.js Web Vitals

If you build on Next.js, drop `<SquasherNextWebVitals />` into your root layout. It bridges Next's [`useReportWebVitals`](https://nextjs.org/docs/app/api-reference/functions/use-report-web-vitals) hook into the same transport, so you get both Core Web Vitals (LCP, CLS, INP, FCP, TTFB) and Next's framework metrics (`Next.js-hydration`, `Next.js-route-change-to-render`, `Next.js-render`) tagged with the current route — without changing your `init()` config.

```tsx app/layout.tsx theme={null}
import { SquasherNextWebVitals } from "@squasher-ai/browser/next";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <SquasherNextWebVitals />
        {children}
      </body>
    </html>
  );
}
```

The component automatically suppresses the SDK's native `web-vitals` collector on mount so Core metrics aren't reported twice. Pass an explicit `path` prop if you want to override the route tag (defaults to `usePathname()`).

<Note>
  This component imports from `next/web-vitals` and `next/navigation` and is **only** valid inside a
  Next.js app. If you're on a different framework, the auto-collector that runs from `init()`
  already captures Core Web Vitals — you don't need this component.
</Note>

## React Error Boundary

If you use React, the package also exports a small error boundary from `@squasher-ai/browser/react`:

```tsx src/providers.tsx theme={null}
"use client";

import { SquasherErrorBoundary } from "@squasher-ai/browser/react";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <SquasherErrorBoundary fallback={<div>Something went wrong.</div>}>
      {children}
    </SquasherErrorBoundary>
  );
}
```

## Session Replay

Replay is on by default once you call `init()`. The recorder batches rrweb events and flushes them automatically in the background, with a final `sendBeacon()` flush during page hide. Password inputs are masked by default.

If you also call `identify()`, Squasher attaches that browser identity to replay uploads so the dashboard can attribute recorded sessions back to the same user context as your frontend errors.

Tune sampling, masking, or block selectors when you record real customer sessions:

```typescript theme={null}
init({
  apiKey: process.env.NEXT_PUBLIC_SQUASHER_API_KEY!,
  projectId: process.env.NEXT_PUBLIC_SQUASHER_PROJECT_ID!,
  replay: {
    sampleRate: 0.05,
    privacy: {
      maskAllText: true,
      blockSelector: ".pii, [data-private]",
    },
  },
});
```

Opt out entirely with `replay: { enabled: false }`.

## Configuration

| Option                  | Type       | Default                            | Description                                                |
| ----------------------- | ---------- | ---------------------------------- | ---------------------------------------------------------- |
| `apiKey`                | `string`   | Required                           | Your public browser ingest key                             |
| `projectId`             | `string`   | Required                           | Your Squasher project ID                                   |
| `endpoint`              | `string`   | `https://ingest.squasher.ai`       | Override the ingest base URL                               |
| `environment`           | `string`   | `undefined`                        | Environment tag                                            |
| `release`               | `string`   | `undefined`                        | Release or commit tag                                      |
| `debug`                 | `boolean`  | `false`                            | Enable SDK debug logging                                   |
| `sampling`              | `object`   | keep all                           | Deterministic rates by outcome                             |
| `vitalsSampleRate`      | `number`   | `1`                                | Sample rate for Web Vitals collection                      |
| `enableVitals`          | `boolean`  | `true`                             | Enable Core Web Vitals collection                          |
| `enableErrorCapture`    | `boolean`  | `true`                             | Install global error handlers                              |
| `enableAutoBreadcrumbs` | `boolean`  | `true`                             | Capture navigation, click, and fetch breadcrumbs           |
| `captureConsoleErrors`  | `boolean`  | `false`                            | Capture `console.error(...)` calls as error events         |
| `maxBreadcrumbs`        | `number`   | `30`                               | Max breadcrumbs retained per session                       |
| `vitalsBufferSize`      | `number`   | `10`                               | Flush Web Vitals after this many measurements              |
| `vitalsFlushIntervalMs` | `number`   | `10000`                            | Max ms between Web Vitals flushes                          |
| `beforeSend`            | `function` | `undefined`                        | Modify or drop events before sending                       |
| `replay`                | `object`   | `{ enabled: true, sampleRate: 1 }` | rrweb replay options. Pass `{ enabled: false }` to disable |

## Notes

* Use `@squasher-ai/nextjs` instead when you need framework-specific Next.js middleware and route wrappers.
* The base browser SDK stays framework-agnostic and works in SPAs, MPAs, and custom frontend shells.
* Review your privacy posture before enabling session replay or logging rich console payloads in production.

## Agent handoff

```text theme={null}
Install @squasher-ai/browser in the client bundle only. Initialize once with NEXT_PUBLIC_ or browser-safe environment variables, configure replay privacy before production traffic, and verify with one browser error plus Web Vitals if enabled.
```
