Providers
Choose official providers, understand support by environment, and route events intentionally.
Providers translate trakoo events into the APIs of the services you already use. You can start with one provider, add another later, or route specific methods and event names to the tools that should receive them.
Client and server product analytics, feature flags, and session replay
OpenPanelClient and server web and product analytics with optional session replay
BentoClient and server lifecycle/email automation for identified users
PirschClient and server privacy-friendly web analytics
EmitKitServer-only event notifications with channel routing
VisitorsClient-only analytics with optional Stripe revenue attribution
ProxyBrowser queue + server ingest helpers for first-party event delivery
Support matrix
| Provider | Client import | Server import | Best for |
|---|---|---|---|
| PostHog | PostHogClientProvider |
PostHogServerProvider |
Product analytics across browser and backend |
| OpenPanel | OpenPanelClientProvider |
OpenPanelServerProvider |
Open-source web and product analytics |
| Bento | BentoClientProvider |
BentoServerProvider |
Identified lifecycle events and email automation |
| Pirsch | PirschClientProvider |
PirschServerProvider |
Privacy-friendly page views and lightweight events |
| EmitKit | — | EmitKitServerProvider |
Notifications and activity channels |
| Visitors | VisitorsClientProvider |
— | Lightweight web analytics and revenue attribution |
| Proxy | ProxyProvider |
ingestProxyEvents, createProxyHandler |
Sending browser events through your own API |
Use client providers from trakoo/providers/client and server providers from trakoo/providers/server.
One event, multiple destinations
import { createClientAnalytics } from 'trakoo/client';
import {
BentoClientProvider,
PostHogClientProvider,
VisitorsClientProvider
} from 'trakoo/providers/client';
const analytics = createClientAnalytics({
providers: [
new PostHogClientProvider({
token: import.meta.env.VITE_POSTHOG_KEY
}),
{
provider: new BentoClientProvider({
siteUuid: import.meta.env.VITE_BENTO_SITE_UUID
}),
methods: ['identify', 'track']
},
new VisitorsClientProvider({
token: import.meta.env.VITE_VISITORS_TOKEN,
persist: true
})
]
});
analytics.track('user_signed_up', {
email: 'ada@example.com',
plan: 'pro'
});
The application emits one typed event. trakoo fans it out to each enabled provider.
Routing
Some providers should not receive every call. Bento is usually better for identified user lifecycle events than anonymous page views. EmitKit is usually better for selected events than high-volume click streams. Wrap a provider in a config object to control exactly which methods and events reach it.
const analytics = createClientAnalytics({
providers: [
new PostHogClientProvider({ token: import.meta.env.VITE_POSTHOG_KEY }),
{
provider: new BentoClientProvider({
siteUuid: import.meta.env.VITE_BENTO_SITE_UUID
}),
methods: ['identify', 'track'],
eventPatterns: ['user_*', 'checkout_*']
}
]
});
Routing options are part of the shared provider config:
| Option | Effect |
|---|---|
methods |
Only call these provider methods |
exclude |
Call every method except these |
events |
Only track these exact event names |
excludeEvents |
Track every event except these names |
eventPatterns |
Track events matching glob-style patterns such as newsletter_* |
methods wins over exclude when both are set. events, eventPatterns, and excludeEvents are mutually exclusive; the runtime logs a warning and uses the highest-priority option.
Browser-to-server delivery
Use the proxy when browser events should go through your domain before reaching server providers.
import { createClientAnalytics } from 'trakoo/client';
import { ProxyProvider } from 'trakoo/providers/client';
export const analytics = createClientAnalytics({
providers: [
new ProxyProvider({
endpoint: '/api/events',
batch: { size: 10, interval: 2000 }
})
]
});
import { createServerAnalytics } from 'trakoo/server';
import {
EmitKitServerProvider,
createProxyHandler
} from 'trakoo/providers/server';
const serverAnalytics = createServerAnalytics({
providers: [
new EmitKitServerProvider({
apiKey: process.env.EMITKIT_API_KEY!,
channelName: 'product-events'
})
]
});
export const POST = createProxyHandler(serverAnalytics);
Build your own provider
If a service is not built in, implement the AnalyticsProvider interface or extend BaseAnalyticsProvider.
import {
BaseAnalyticsProvider,
type BaseEvent,
type EventContext
} from 'trakoo/client';
export class CustomProvider extends BaseAnalyticsProvider {
name = 'CustomProvider';
initialize() {}
track(event: BaseEvent, context?: EventContext) {
console.log(event.action, event.properties, context);
}
identify(userId: string, traits?: Record<string, unknown>) {}
pageView(properties?: Record<string, unknown>, context?: EventContext) {}
reset() {}
}
