Skip to main content
Use @squasher-ai/browser in apps that run in the browser: React, Vue, Svelte, or plain JavaScript. This page is tested with version 0.5.0. For a Next.js app, follow the Next.js SDK page instead.

What the SDK captures

Install the SDK

Add your ingest key and project ID to the environment of your build. This example uses Vite, which exposes variables that start with VITE_:
.env
To get both values, see Create an ingest key. The key is part of your JavaScript bundle, so anyone who opens your site can read it. An ingest key can send events to your project, but it cannot read data.

Keep the browser integration first-party

Bundle the SDK with your application. Do not load it from a third-party CDN or paste a vendor <script src="https://…"> tag into your pages. A bundled SDK is served with your release, so a vendor account or CDN change cannot replace code on your site without a deployment. Use a dedicated ingest-only key for browser code. Never expose a server key, read key, or secret in HTML.

Send data through your own domain

Ad blockers and privacy tools often block requests to analytics and monitoring domains. Send the SDK’s requests through a route on your own site instead. The browser then talks only to your origin, and your Content-Security-Policy can keep connect-src 'self'. createSquasherProxy from @squasher-ai/browser/proxy returns a handler that takes a Request and returns a Response. It forwards only the SDK’s upload routes for your project and key. It drops cookies, Authorization, and every other header that the SDK does not send, refuses requests from other sites, limits the body size, and does not follow redirects. Pick a neutral route name, such as /api/t. Names like /analytics or /tracking are more likely to match blocker rules.
Then point the SDK at the route:
src/main.ts
The handler runs in any runtime with the Fetch API: Next.js route handlers, Cloudflare Workers, Hono, Bun, Deno, and Node.js 18 or later.

Initialize the SDK

Call init once, when your app starts, before it renders.
src/main.ts
init starts error capture, Web Vitals, and session replay. release is optional: set it to the same value on every page of one deploy, for example the git commit SHA.

Capture React errors

Wrap your app in SquasherErrorBoundary. When a component throws during render, the boundary sends the error with the component stack and shows the fallback.
src/main.tsx
Call init before this code runs. The boundary also takes an onError callback.

Capture errors that you catch

src/cart.ts
The second argument is optional. It adds your own fields to the event. setUser adds the user to every later event. captureMessage("Checkout opened", "info") sends a message instead of an error.

Configure session replay

Session replay records each browser session, so that you can watch what the user did before an error. It is on by default. Replay is private by default. It masks all page text and all typed values, and it shows images, video, audio, SVG, and canvas as empty boxes. Password, payment card, and one-time-code fields are always left out, and the recorded page URL has no query string or fragment. Each recorded session counts toward the replays in your plan.
src/main.ts
To show text on pages without personal data, set maskAllText: false. Text in elements with the squasher-mask class or the data-squasher-mask attribute stays masked. blockSelector replaces the matching elements with an empty box. To turn replay off, set replay: { enabled: false }. See Session replay for all options.
Product analytics is coming soon. It is available only on plans that include product analytics. On other plans, Squasher does not accept product events.
Product analytics records page views and the events that you send with track. The SDK sends product events only after the visitor gives consent. The consent option sets the state at startup. The default is "denied". When your consent banner gets an answer, call setConsent:
src/consent.ts
The SDK writes nothing to localStorage before consent is "granted". Each product event that the SDK sends carries consent: "granted". Squasher rejects product events that do not carry this marker. If you send product events from your server, set consent: "granted" on each event, and only for visitors who gave consent. You are responsible for getting consent from your visitors. The marker records your consent decision. By default, consent controls only product analytics. Errors, Web Vitals, and session replay do not wait for consent. To make them wait too, set consentMode: "strict". In strict mode, the SDK sends errors, Web Vitals, and replays only while consent is "granted", and it stops when consent becomes "denied".

Send product events

src/checkout.ts
  • track(name, properties) records a custom event. A name can have up to 200 characters.
  • page(name, properties) records a page view. Both arguments are optional.
  • identify(userId, traits) links this visitor to your user ID. Later events include the user ID. The traits go to the properties of the identify event.
Properties can have up to 32 keys. A key can have up to 64 characters. A string value can have up to 512 characters. The SDK converts objects and arrays to JSON text. To record page views automatically, set analytics: { autoPageviews: true }. The SDK then records the first page and each navigation in a single-page app. It records a new page view only when the path changes.

What the SDK removes

Before the SDK sends a product event, it removes personal data from the page address:
  • It removes the query string and the fragment (the part after #). To keep a query parameter, add its name to analytics.allowedQueryParams. The SDK then sends its value as the property query.<name>, not in the path. These properties count toward the limit of 32 keys.
  • It replaces path segments that look like IDs with :id. Examples are UUIDs, long hexadecimal values, numbers with 6 or more digits, email addresses, and long tokens.
  • It keeps only the host name of the referrer, and only when it is a different site.
  • It keeps the utm_source, utm_medium, utm_campaign, utm_term, and utm_content values.
  • It keeps the ad click IDs gclid, fbclid, msclkid, ttclid, li_fat_id, and twclid as text, for revenue attribution. Squasher does not send them to an ad platform.
  • An event held while consent is pending (consentBuffer: "pending") is sent after the grant without any data from the page address except the path: no UTM values, click IDs, referrer, or query.<name> properties. Its own property keys and text values are checked at every depth of objects and arrays: text with a ? or # that starts with ? or # (after spaces) or contains :, /, or \ is cut at the first ? or #. So /checkout?email=… is sent as /checkout and mailto:[email protected]?body=… as mailto:[email protected]; plain text such as pro? stays as it is. When two keys become equal, the first is kept. A value that refers to itself, or is nested more than 32 levels deep, is left out. If a property graph is unsafe or too large to inspect safely, the SDK leaves out that value and continues sending the event.
Squasher does not store the visitor IP address. It records only the country, the browser family, and the operating system family.

Log out and delete data

Call reset() when a user logs out. The SDK makes a new anonymous ID and a new session, and later events have no user ID. Call forget() when a visitor asks you to delete their data. The SDK removes the stored IDs and the session ID, deletes the events that it did not send, and sets consent to "denied".

Send a test error

Add a button that throws, and select it once in your running app:
The SDK sends each error at once. Then select Issues in the sidebar of your project. The test error is at the top of the list. If it does not appear, see Troubleshooting.

Options

sampling applies to events such as errors and messages, not to Web Vitals or replays. It treats events at warning level and above as errors, so errorRate applies to them.

Limits

  • init throws when apiKey or projectId is empty, and when you call it a second time. Call close() before you call init again.
  • The SDK sends each event once. It does not retry when the request fails.
  • Stack traces from a minified bundle point at the minified files until you upload source maps for the release. When your bundler injects debug IDs, the SDK reads its debug ID registry and sends the debug ID of each frame’s file, so Squasher finds the map even without a release.
  • The SDK sends breadcrumbs, but Squasher does not store them.

Give the setup to a coding agent

Copy this prompt into your coding agent to install the SDK the same way:

Next steps

Session replay

Watch what the user did before an error.

Upload source maps

Show the original source of minified frames.

Next.js SDK

Capture server and browser errors in a Next.js app.

Read AI triage

Learn what the triage summary tells you.