Spacerr uses PostHog for product analytics and keeps tracking optional. Analytics are initialized on the client only when tracking is enabled, and private admin pages are skipped.
What It Includes
The analytics layer includes:
- PostHog browser initialization.
- Route based tracking through the root provider.
- Admin route exclusion.
- Optional tracking controlled by environment configuration.
- Billing interaction events.
- User activity tracking for last active state.
- A clean place to add custom product events.
Provider
The analytics provider lives in src/providers/posthog.provider.tsx and wraps the app from src/app/layout.tsx.
export function PostHogProvider({ children }: { children: React.ReactNode }) {
return (
<>
<Suspense fallback={null}>{children}</Suspense>
<Suspense fallback={null}>
<PostHogRouteTracker />
</Suspense>
</>
)
}The tracker initializes PostHog during idle time and skips admin pages.
const isAnalyticsEnabled = ClientEnv.NEXT_PUBLIC_ANALYTICS_TRACKING?.toLowerCase() === "on"
const isAdminPage = pathname ? isPathWithinRoute(pathname, WebRoutes.admin.path) : false
if (!isAnalyticsEnabled || isAdminPage) {
return
}Use the setup guide for the PostHog project token and host values. This page covers how analytics are wired in the app.
Billing Events
Billing emits product events from src/features/billing.
export const BILLING_TRACKING_EVENT_NAME = "billing:interaction"
export const BILLING_TRACKING_EVENTS = {
ctaClicked: "cta_clicked",
checkoutRedirected: "checkout_redirected",
portalRedirected: "portal_redirected",
ctaFailed: "cta_failed",
} as constUse this pattern for important product actions where the UI should not import analytics provider code directly.
User Activity
User activity tracking updates account activity state separately from PostHog.
src/features/auth/components/user-activity-tracker.tsx
src/features/auth/hooks/use-mutate-track-user-activity.ts
src/app/api/account/activity/route.tsThis is used for product state such as lastActiveAt. It is not a replacement for analytics events.
Custom Events
For new product events, keep event names in the feature that owns the behavior.
export const PRODUCT_TRACKING_EVENT_NAME = "product:interaction"
export const PRODUCT_TRACKING_EVENTS = {
actionStarted: "action_started",
actionCompleted: "action_completed",
} as constPrefer feature owned constants over scattered event strings. This keeps analytics changes easy to find and review.
Privacy Boundaries
Do not track admin pages, private files, raw prompts, file contents, secrets, payment keys, or full user generated content. Track product actions and state changes, not sensitive payloads.
Where To Customize
Use these files first:
src/providers/posthog.provider.tsxfor PostHog initialization and route tracking.src/app/layout.tsxfor provider placement.src/features/billing/constants/billing-tracking.constants.tsfor billing event names.src/features/billing/utils/track-billing-event.tsfor billing event dispatch.src/features/auth/components/user-activity-tracker.tsxfor user activity tracking.src/features/auth/hooks/use-mutate-track-user-activity.tsfor activity mutations.