chmonitor
OperateAdvanced

Product Analytics

Opt-in PostHog product analytics across every chmonitor surface — off by default, Do Not Track respected, cookieless, no session recording.

chmonitor can optionally send product analytics — automatic pageviews, autocaptured interactions (clicks, form submits), client- and server-side crashes, plus explicit conversion funnel events (signups, cluster connects, upgrades, checkouts) — to PostHog for the hosted SaaS product's growth/business side. It is OFF by default — a hard no-op — until you configure an analytics key.

Coverage spans every surface of chmonitor.dev: the dashboard (dash.chmonitor.dev, incl. server/API crash capture), the docs site (docs.chmonitor.dev), the landing site, and the blog.

This is a different system from Product Telemetry (anonymous, on-by-default, aggregate OSS instance telemetry to chmonitor's own collector) and from Self-Tracking (writes usage events to your own ClickHouse instance). Product analytics exists purely to measure the marketing/signup/upgrade funnel and is never required to run chmonitor.

Opt in — off by default

No key, no network call

Without CHM_ANALYTICS_KEY (dashboard) / VITE_ANALYTICS_KEY (docs) / PUBLIC_ANALYTICS_KEY (landing + blog) set, none of this code makes a network call, loads PostHog, or sets a cookie. Self-hosted instances stay completely untouched by default.

VariableSurfacePurpose
CHM_ANALYTICS_KEYDashboard (derives client VITE_ANALYTICS_KEY; also read server-side for crash capture)PostHog project key. Empty = disabled.
CHM_ANALYTICS_HOSTDashboard (derives client VITE_ANALYTICS_HOST)PostHog ingestion host. Empty = PostHog Cloud (US).
VITE_ANALYTICS_KEYDocs site (TanStack Start)PostHog project key. Empty = disabled.
VITE_ANALYTICS_HOSTDocs site (TanStack Start)PostHog ingestion host. Empty = PostHog Cloud (US).
PUBLIC_ANALYTICS_KEYLanding + blog (Astro)PostHog project key. Empty = disabled.
PUBLIC_ANALYTICS_HOSTLanding + blog (Astro)PostHog ingestion host. Empty = PostHog Cloud (US).

Both *_HOST variables let you point at a self-hosted PostHog instance instead of PostHog Cloud, keeping the whole stack self-hostable in spirit.

Do Not Track

The browser navigator.doNotTrack signal is checked before analytics initializes — when set, init is skipped entirely. The dashboard additionally honors the cross-tool DO_NOT_TRACK/ VITE_DO_NOT_TRACK convention already used by telemetry.

Events

Landing site

EventWhen it fires
landing_viewThe marketing home page (/) loads
pricing_viewThe /pricing page loads
cta_clickA tracked call-to-action link is clicked (target = a static identifier, e.g. hero-primary)

Dashboard

EventWhen it fires
signupA Clerk account created within the last 2 minutes loads the app (approximates "just signed up")
cluster_connectA ClickHouse connection is added and saved
sample_cluster_connectedThe "Try with sample ClickHouse" read-only preset is connected
sample_to_real_convertedA non-sample host is added after the sample was connected
first_chart_renderThe first chart renders with real data (once per page load)
agent_messageA message is sent to the AI agent
upgrade_clickAn "Upgrade" call-to-action is clicked
checkout_startedA Polar checkout session is created, right before redirect

What is captured

  • Automatic pageviews and pageleaves on every surface (SPA route changes included)
  • Autocaptured interactions — clicks and form submissions (PostHog autocapture)
  • Crashes — client-side React error boundaries report a $exception; the dashboard Worker additionally reports server/API exceptions via PostHog's stateless /capture/ endpoint (the Worker runs on workerd, so it cannot use posthog-node)
  • Explicit funnel events — the typed events listed above

What is still NOT collected

  • Session recordingsdisable_session_recording: true on every surface
  • No identify() is ever called with a user-derived id — every distinct id stays PostHog's anonymous default
  • Explicit dashboard events are redacted defensively before leaving the process, reusing the same redactProps allowlist Product Telemetry uses (drops any prop whose key implies sensitive content, or whose value looks like an email/IP/URL); server-side crash props are redacted the same way

Autocapture can record clicked-element text

Because autocapture is enabled, PostHog may record the text of clicked elements. The two safety rails that keep self-hosted instances silent are unchanged: it is off unless a key is set, and the browser Do Not Track signal disables it entirely.

PostHog is configured cookieless (persistence: 'localStorage'), so no cookie banner is required for this feature.

Anonymous by design

No call site ever calls PostHog's identify() with anything user-derived — every distinct id stays PostHog's anonymous default.

On this page