Event Tracking
Track user actions, page views, and business events. Events are the foundation for analytics, funnels, and experiment results.
Tracking Events
Client-side
Use the useTrack hook inside any client component to fire a named event with optional properties.
import { useTrack } from "@sheepit-ai/react";
function ProductPage({ product }) {
const track = useTrack();
return (
<button onClick={() => track("add_to_cart", {
productId: product.id,
price: product.price,
currency: "USD"
})}>
Add to Cart
</button>
);
}Server-side
Use getGoaTech() from @sheepit-ai/server/nextjs to track events from React Server Components, route handlers, or any Node.js environment. Pass the user ID as the third argument so the event is attributed correctly.
import { getGoaTech } from "@sheepit-ai/server/nextjs";
const gt = getGoaTech();
gt.track("order_completed", { orderId, total, items: items.length }, userId);Event Properties
Events accept an optional properties object as the second argument. Follow these conventions to keep your data consistent and queryable.
- Use snake_case for property names
- Keep properties flat — avoid deep nesting
- Include relevant context such as IDs, amounts, and categories
- Event names have a 200 character limit
track("purchase_completed", {
order_id: "ord_abc123",
total: 149.99,
currency: "USD",
item_count: 3,
payment_method: "stripe",
coupon_applied: true,
});Automatic Events
The SDK emits several events automatically — you do not need to call track() for these.
$page_view— fired by thePageViewTrackercomponent on each navigation (includes pathname and search params)$flag_exposure— recorded once per session per flag when a flag is evaluated$experiment_exposure— recorded once per session per experiment when a variant is assigned$identify— emitted whenidentify()is called$logout— emitted whenreset()is called
Event Context
Every event is automatically enriched with the following fields before it leaves the device. You never need to set these manually.
device_id— persistent anonymous device identifieranonymous_id— session-scoped anonymous IDsession_id— current session IDuser_id— set afteridentify()is calledtimestamp— ISO 8601 timestampsdk_version— SDK version string
Batching & Flushing
Events are queued locally and sent in batches to reduce network overhead. The following defaults apply and can be overridden in your SDK configuration.
- Flush interval — every 5 seconds (configurable via
flushInterval) - Flush size — when 20 events accumulate on the client, 50 on the server (configurable via
flushSize) - Max queue — 1,000 events on the client (configurable via
maxQueueSize), 10,000 on the server (configurable viamaxBufferSize) - Auto-flush — on page unload via
beforeunloadandpagehide - Manual flush — call
flush()when you need to guarantee delivery before a navigation or side effect
const gt = useGoaTech();
async function handleBeforeNavigate() {
await gt.flush(); // Force send all queued events
}Offline Support
When the user goes offline, events are stored in an offline queue (up to 500 events). When connectivity returns, the queue drains automatically. Failed requests retry with exponential backoff at 1 s, 5 s, and 15 s intervals.