Analytics API
Every method on the Analytics instance (yes, all of them)
Analytics API
The full reference for the Analytics class. Everything the SDK can do is listed here.
Getting an Instance
Three ways to get started. Pick your favorite.
createAnalytics(config)
Create a new instance. You manage its lifecycle.
import { createAnalytics } from '@thisbefine/analytics';
const analytics = createAnalytics({
apiKey: 'tif_your_api_key',
});Parameters: config: AnalyticsConfig
Returns: Analytics
initAnalytics(config)
Initialize the global singleton. Use this if you want to access the same instance from anywhere.
import { initAnalytics } from '@thisbefine/analytics';
initAnalytics({
apiKey: 'tif_your_api_key',
});Parameters: config: AnalyticsConfig
Returns: Analytics
getAnalytics()
Get the global singleton (if you initialized it).
import { getAnalytics } from '@thisbefine/analytics';
const analytics = getAnalytics();
if (analytics) {
analytics.track('event_name');
}Returns: Analytics | null (null if you forgot to call initAnalytics)
Event Tracking
The fun part. Actually tracking things.
track(event, properties?)
Track something happening. A click, a purchase, a signup—whatever you care about.
analytics.track('button_clicked', {
buttonId: 'cta-hero',
variant: 'primary',
});Prop
Type
Returns: void
page(name?, properties?)
Track a pageview. Essential for understanding where users spend their time.
// Basic - captures URL, referrer, title automatically
analytics.page();
// Named
analytics.page('Dashboard');
// With extra context
analytics.page('Product Page', {
productId: 'prod_123',
category: 'electronics',
});Prop
Type
Returns: void
Automatically captured:
url- Full URLpath- Just the pathreferrer- Where they came fromtitle- Page title
Lifecycle Events
Built-in methods for common SaaS events. See the Lifecycle Events Guide for full documentation.
User Lifecycle
analytics.signup({ method: 'google', plan: 'free' });
analytics.login({ method: 'passkey' });
analytics.logout({ reason: 'manual' });
analytics.accountDeleted({ reason: 'not_using', tenure: 180 });Subscription Lifecycle
analytics.subscriptionStarted({ plan: 'pro', mrr: 29 });
analytics.subscriptionCancelled({ plan: 'pro', reason: 'too_expensive' });
analytics.subscriptionRenewed({ plan: 'pro', renewalCount: 3 });
analytics.planUpgraded({ fromPlan: 'free', toPlan: 'pro' });
analytics.planDowngraded({ fromPlan: 'pro', toPlan: 'free' });
analytics.trialStarted({ plan: 'pro', trialDays: 14 });
analytics.trialEnded({ plan: 'pro', converted: true });Engagement
analytics.inviteSent({ inviteEmail: 'team@example.com', role: 'member' });
analytics.inviteAccepted({ invitedBy: 'user_123' });
analytics.featureActivated({ feature: 'api_keys', isFirstTime: true });These methods are type-safe and trigger automatic insights (churn alerts, subscriber notifications).
User Identification
Turn anonymous visitors into real people.
identify(userId, traits?)
"This is user_123 and here's what we know about them."
analytics.identify('user_123', {
email: 'jane@example.com',
name: 'Jane Doe',
plan: 'pro',
createdAt: '2025-01-15',
});Prop
Type
Returns: void
group(accountId, traits?)
"This user belongs to workspace_456." Essential for B2B apps.
analytics.group('workspace_456', {
name: 'Acme Corp',
plan: 'enterprise',
mrr: 5000,
industry: 'Technology',
});Prop
Type
Returns: void
reset()
Clear everything and start fresh. Call this on logout.
await logout();
analytics.reset();Returns: void
What it does:
- Flushes any pending events
- Clears userId and user traits
- Clears accountId and account traits
- Generates a new anonymousId
- Starts a new session
Basically: "New phone, who dis?"
getUser()
Peek at the current user state.
const user = analytics.getUser();
console.log(user.anonymousId); // Always there
console.log(user.userId); // After identify()
console.log(user.traits); // User infoReturns: UserState
interface UserState {
anonymousId: string;
userId?: string;
traits?: UserTraits;
accountId?: string;
accountTraits?: AccountTraits;
}Error Tracking
When things go wrong (and they will).
captureException(error, context?)
Catch an error and send it to us.
try {
await riskyOperation();
} catch (error) {
analytics.captureException(error as Error, {
operation: 'riskyOperation',
userId: user.id,
});
}Prop
Type
Returns: void
captureMessage(message, level?, context?)
Report an error without an Error object. For when you detect something fishy.
analytics.captureMessage(
'Payment processing timeout',
'error',
{ orderId: 'ord_123' }
);Prop
Type
Returns: void
addBreadcrumb(breadcrumb)
Leave a trail of crumbs leading to the error. Like Hansel and Gretel, but for debugging.
analytics.addBreadcrumb({
type: 'custom',
message: 'User started checkout',
data: { cartItems: 3, total: 149.97 },
});Prop
Type
Returns: void
Logging
Structured logs. Better than console.log('here 3').
log(message, level, metadata?)
Send a log entry.
analytics.log('User exported data', 'info', {
format: 'csv',
rowCount: 1000,
duration: 234,
});Prop
Type
Returns: void
Privacy & Control
Respect your users. They'll appreciate it.
optOut()
Stop tracking this user. Completely.
analytics.optOut();Returns: void
What happens:
- No events are tracked
- Nothing is sent to the server
- Choice persists in localStorage
optIn()
Resume tracking (after they opted out).
analytics.optIn();Returns: void
isOptedOut()
Check if the user opted out.
if (!analytics.isOptedOut()) {
analytics.track('some_event');
}Returns: boolean
Event Queue
Under the hood, events are batched for efficiency.
flush()
Force-send all pending events right now. Don't wait for the batch.
// Before navigating away
await analytics.flush();
window.location.href = '/external-page';Returns: Promise<void>
Use this before:
- Navigating to an external page
- Closing a modal where timing matters
- Any action where you need immediate delivery
Otherwise, let the SDK batch events automatically. It's more efficient.