Tracking
Turn analytics providers on and off from the admin, with no env-var juggling across environments.
Toggle analytics on and off from the Payload admin: flip a switch for PostHog, Google Tag Manager, or Vercel Analytics, paste in the keys, and the right scripts load on the next page view. No environment variables, no redeploy.
Overview
Tracking moves your analytics setup out of environment configuration and into Payload. The plugin registers a single Tracking global that holds the settings for every supported provider (PostHog, Google Tag Manager, and Vercel Analytics), each behind its own toggle.
That makes analytics an editorial decision instead of a deployment one. Turning a provider on, swapping a key, or trying a different tool is an edit in the admin rather than an env-var change you repeat across every environment. And because a provider only loads when its toggle is on, a site that uses none of them ships none of their scripts.
How it works
Three pieces work together:
- The
Trackingglobal is the single source of truth. Each provider gets an on/off toggle in the sidebar (everything starts off), and flipping a toggle on reveals that provider's settings group: PostHog asks for a public key and host (defaulting tohttps://us.i.posthog.com) plus optional autocapture URL allow / ignore lists, Google Tag Manager asks for a container ID, and Vercel Analytics is just the toggle. Each provider's keys are only required while its toggle is on, so you can always save with unused providers switched off. - The
TrackingProvideris a client component you mount once at your app root. You fetch the global on the server and pass it in as a prop; the provider reads the toggles and renders only the per-provider components that are switched on (PostHogProvider,GoogleTagManagerProvider,VercelProvider). A provider that's off is never rendered, so its script never loads and nothing gets sent. The three SDKs (posthog-js,@next/third-parties,@vercel/analytics) are optional peer dependencies, so only the ones you actually install end up in your app. - Caching ties them together. Your layout reads the global through
getCachedTracking, which caches it under thetrackingtag. Saving the global in the admin revalidates that tag, so a toggle you flip takes effect on the next page view, with no rebuild.
PostHog loads once, on the first page view outside /admin, and relies on autocapture: pageviews and interactions are recorded automatically, narrowed by the optional URL allow / ignore lists.
Using it
The frontend wiring is one fetch and one wrapper in your root layout. Fetch the Tracking global server-side with the cached getter and hand it to TrackingProvider. This is exactly how the atomic-payload template wires it:
// app/(frontend)/layout.tsx (a Server Component)
import { draftMode } from 'next/headers'
import { getCachedTracking } from '@pro-laico/tracking/cache'
import { TrackingProvider } from '@pro-laico/tracking/provider'
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const { isEnabled: draft } = await draftMode()
const tracking = await getCachedTracking(draft)
return (
<html lang="en">
<body>
<TrackingProvider tracking={tracking}>{children}</TrackingProvider>
</body>
</html>
)
}If tracking is missing (the global has never been saved, or you forgot the prop), the provider just renders your app and loads nothing.
From then on, analytics is managed entirely in the admin: open the Tracking global, turn a provider on, fill in its keys, and save. Turning a toggle off stops that provider's script from loading without deleting its settings, so you can switch it back on later.
Configuration
Enabling a provider end to end, with PostHog as the example. First install its SDK; the SDKs are optional peers, so add only the ones you turn on (posthog-js for PostHog, @next/third-parties for Google Tag Manager, @vercel/analytics for Vercel Analytics):
pnpm add posthog-jsThen, in the admin, open the Tracking global, flip on PostHog, paste your project's public key, confirm the host (it defaults to https://us.i.posthog.com), and save. The save revalidates the cached global, and PostHog loads on the next page view.
The same flow applies to the others: Google Tag Manager asks for its container ID (GTM-XXXXXXX), and Vercel Analytics needs only the toggle.
There are no environment variables to set: the plugin reads none, and every key (the PostHog key and host, the GTM container ID) is stored in the global, so the same build works across environments. For the plugin's own options (enabled, includeTrackingGlobal) and the full export list, see the plugin options.