Understand how users experience your frontend without adding page-view instrumentation. The beacon collects page views, scroll depth, Web Vitals, browser errors, and click events from elements you mark with data-analytics.
What Gets Tracked
The beacon automatically collects the following on every page view:
| Category | Data |
|---|---|
| Page context | URL, path, referrer, title (query strings stripped for privacy) |
| Device | Screen dimensions, viewport size, pixel ratio, user agent, language |
| Geolocation | Country, region, city, timezone, and coarse coordinates from the location service |
| Performance | Load time, DOM ready, TTFB |
| Web Vitals | FCP, LCP, CLS, INP |
| Engagement | Scroll depth, time on page, visibility sessions |
| UTM params | utm_source, utm_medium, utm_campaign, utm_term, utm_content |
| SPA navigation | Virtual page views on pushState/replaceState |
| Errors | JavaScript errors and unhandled promise rejections |
Events are batched, then sent when the user navigates away or changes routes. The beacon sends on visibilitychange, pagehide, and beforeunload, forces a send on SPA navigation, and uses a sessionStorage fallback to recover data if unload events don't fire.
Configuration
Analytics are enabled by default. Configure tracking in createApp():
import { createApp } from '@agentuity/runtime';
export default await createApp({
analytics: {
enabled: true,
trackClicks: true,
trackScroll: true,
trackOutboundLinks: true,
trackForms: false,
trackWebVitals: true,
trackErrors: true,
trackSPANavigation: true,
requireConsent: false,
sampleRate: 1,
excludePatterns: ['/admin/*'],
globalProperties: { app: 'docs' },
},
});| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable or disable analytics |
requireConsent | boolean | false | Wait for explicit consent before tracking |
trackClicks | boolean | true | Track clicks on elements with data-analytics attribute |
trackScroll | boolean | true | Track scroll depth milestones (25%, 50%, 75%, 100%) |
trackOutboundLinks | boolean | true | Track clicks that leave the current origin |
trackForms | boolean | false | Track form submissions |
trackWebVitals | boolean | true | Track Core Web Vitals (FCP, LCP, CLS, INP) |
trackErrors | boolean | true | Track JavaScript errors and unhandled rejections |
trackSPANavigation | boolean | true | Track client-side route changes via pushState/replaceState |
sampleRate | number | 1 | Sample rate from 0 to 1 (1 = track 100% of page views) |
excludePatterns | string[] | [] | URL path patterns to skip |
globalProperties | Record<string, unknown> | {} | Properties attached to every analytics event |
To disable analytics entirely:
import { createApp } from '@agentuity/runtime';
export default await createApp({
analytics: false,
});Custom Event Tracking
Data Attributes
Add data-analytics to any element to track clicks without writing JavaScript. The beacon records these as click:<value> custom events:
<button data-analytics="signup_button">Sign Up</button>
<a href="/pricing" data-analytics="pricing_link">View Pricing</a>JavaScript API
Track events programmatically using the @agentuity/frontend package:
import { track, getAnalytics } from '@agentuity/frontend';
// Track a custom event
track('purchase_completed', {
productId: 'prod_123',
amount: 99.99,
currency: 'USD',
});
// Access the full analytics client for identify and flush
const analytics = getAnalytics();
analytics?.identify('user_456', { plan: 'pro' });
analytics?.flush();The same client is also available globally as window.agentuityAnalytics for non-module contexts (inline scripts, third-party integrations):
window.agentuityAnalytics?.track('cta_clicked', { location: 'hero' });The analytics client initializes when the beacon script loads. In module code, getAnalytics() returns null until the beacon is ready. In React, check the ready value from useAnalytics() before relying on immediate identify() or flush() calls.
React Integration
If you already use @agentuity/react, its compatibility hooks can track analytics from React components. For new apps, prefer @agentuity/frontend for browser-level analytics calls.
useAnalytics
import { useAnalytics } from '@agentuity/react';
function ProductPage({ productId }: { productId: string }) {
const { track, trackClick, identify, ready } = useAnalytics();
const handlePurchase = () => {
track('purchase_started', { productId });
};
return (
<div>
<button onClick={trackClick('add_to_cart', { productId })}>
Add to Cart
</button>
<button onClick={handlePurchase}>Buy Now</button>
</div>
);
}| Property | Type | Description |
|---|---|---|
track | (eventName, properties?) => void | Track a custom event |
trackClick | (eventName, properties?) => (event) => void | Returns a click handler that tracks an event |
identify | (userId, traits?) => void | Identify the current user |
flush | () => void | Force-send pending events |
ready | boolean | true when the analytics client is available |
useTrackOnMount
Track an event when a component mounts:
import { useTrackOnMount } from '@agentuity/react';
function ProductPage({ productId }: { productId: string }) {
// Fires once per component instance by default
useTrackOnMount({
eventName: 'product_viewed',
properties: { productId },
});
return <div>Product {productId}</div>;
}| Option | Type | Default | Description |
|---|---|---|---|
eventName | string | - | Event name to track |
properties | object | - | Event properties |
once | boolean | true | Only track once per component instance |
withPageTracking
Higher-order component that tracks a page_view event on mount:
import { withPageTracking } from '@agentuity/react';
function HomePage() {
return <div>Welcome!</div>;
}
export default withPageTracking(HomePage, 'home');Privacy
The analytics beacon keeps request data separate from agent sessions:
- No agent session for page views: Web analytics uses a signed
atid_athread cookie and does not createsess_...records orx-session-idheaders - Visitor IDs use localStorage: Users can clear
agentuity_visitor_idfrom browser storage - Query strings stripped: URLs are sanitized before sending to prevent leaking tokens or PII
- Sampling: Use
sampleRateto reduce data collection on high-traffic pages
Users can opt out of tracking programmatically:
import { isOptedOut, setOptOut } from '@agentuity/frontend';
function PrivacyToggle() {
const optedOut = isOptedOut();
return (
<button onClick={() => setOptOut(!optedOut)}>
{optedOut ? 'Enable Analytics' : 'Disable Analytics'}
</button>
);
}To disable the beacon for an app, set analytics: false in createApp().
In development, analytics data is logged to the browser console instead of being sent to the collection endpoint. This lets you verify tracking behavior without generating real data.
Next Steps
- React Hooks:
useAnalyticsand other hooks for React integration - Logging: Collected logs for agents and routes
- Tracing: OpenTelemetry spans for performance debugging