Vanilla JavaScript / TypeScript
If you're not using React, Vue, or Inertia — or you're building a small widget that doesn't justify a framework — @larabug/browser is all you need.
Install
npm install @larabug/browser
Initialise
Call init() once, as early in your app's startup as possible:
import * as LaraBug from '@larabug/browser';
LaraBug.init({
dsn: 'https://login_key:project_key@www.larabug.com/api/log',
environment: import.meta.env.MODE,
release: import.meta.env.VITE_APP_VERSION,
});
The moment init() returns, LaraBug has already installed global error and unhandledrejection listeners. Everything thrown from your app after this point gets captured automatically.
Manual capture
You rarely need this, but when you do:
try {
riskyOperation();
} catch (error) {
LaraBug.captureException(error, {
// Optional context merged into the event
operation: 'riskyOperation',
attempt: 3,
});
}
For non-error messages (logs, warnings, debugging):
LaraBug.captureMessage('Checkout started', 'info');
LaraBug.captureMessage('Payment gateway responded slowly', 'warning');
User context
Tell LaraBug who's using the app. The user object gets attached to every subsequent event until you call setUser(null):
LaraBug.setUser({
id: currentUser.id,
email: currentUser.email,
name: currentUser.name,
});
// On logout:
LaraBug.setUser(null);
User objects run through the DataFilter before being sent, so fields matching the blacklist (password, token, ...) get scrubbed even if you accidentally include them.
Breadcrumbs
Breadcrumbs are captured automatically for console calls, fetch/XHR, navigation, and hash changes. If you want to add your own:
LaraBug.addBreadcrumb({
type: 'user',
category: 'auth',
message: 'User clicked sign in',
level: 'info',
});
The last 100 breadcrumbs are attached to every captured event.
Tags and context
Tags are short labels you can group events by. Context is free-form data:
LaraBug.setTag('feature_flag_new_checkout', 'enabled');
LaraBug.setTag('ab_test', 'variant_b');
LaraBug.setContext('checkout', {
cart_total: 99.99,
items_count: 3,
});
Both persist until you overwrite them or the page navigates away.
Dropping events
If you want the final say on what gets sent, pass a beforeSend callback. Return null to drop the event entirely, or mutate and return it to send:
LaraBug.init({
dsn: '...',
beforeSend: (event) => {
// Drop errors from third-party scripts
const topFrame = event.exception?.stacktrace?.[0];
if (topFrame?.filename?.includes('google-analytics')) {
return null;
}
return event;
},
});
beforeSend runs after the built-in DataFilter, so you only see safe data — you don't need to scrub passwords yourself.