diff --git a/ANALYTICS.md b/ANALYTICS.md new file mode 100644 index 0000000..c1985b3 --- /dev/null +++ b/ANALYTICS.md @@ -0,0 +1,54 @@ +# Analytics on docs.openadapt.ai + +This documentation site uses privacy-safe, build-time analytics. This file lives +at the repository root (not under `docs/`) so it does not affect the published +site or `mkdocs build --strict` navigation. + +## What is tracked + +The site reports into two destinations that share one event taxonomy across all +OpenAdapt web properties: + +- **PostHog** (product analytics), and +- **Google Analytics 4** (Material's native integration). + +Tracked events: + +| Event | Properties | Notes | +| --- | --- | --- | +| `$pageview` | (automatic) | PostHog fires this via Material's `location$` observable so it works under `navigation.instant`. GA pageviews are handled natively by Material. | +| `docs_search` | `query_length` | Only the LENGTH of the search query is captured, never the raw text. Debounced by ~800ms. | +| `outbound_click` | `destination`, `href` | `destination` is one of `app`, `download`, or `github`. `href` is host + path only, with the query string stripped. | + +Search and pageview events are also emitted to Google Analytics where Material's +native integration does not already cover them. + +## Shared project + +Both destinations are shared with the marketing site. PostHog reuses the same +project (via the same env var names below), so all OpenAdapt properties report +together. + +## Environment variables (set at BUILD time) + +Analytics is a static build, so keys are read when `mkdocs build` runs, not at +page-serve time. Set these in the docs deploy/CI environment: + +- `NEXT_PUBLIC_POSTHOG_KEY`: PostHog project key. Reuse the SAME key as the + marketing site so everything lands in one PostHog project. When this is unset, + no PostHog script is emitted into the built HTML at all (a hard no-op). +- `NEXT_PUBLIC_POSTHOG_HOST`: PostHog API host. Defaults to + `https://us.i.posthog.com`. +- `GOOGLE_ANALYTICS_KEY`: GA4 measurement ID. Optional; defaults to the existing + `G-CJ01Y19XJN`. GA measurement IDs are public (non-secret). + +## Privacy properties + +- **No PHI or PII.** These are public documentation pages only. +- **Do-Not-Track is respected.** When the browser sends a Do-Not-Track signal, + PostHog is never loaded or initialized. +- **Conservative capture.** Search records only `query_length` (never the raw + query), and outbound links record only host + path (never the query string). +- **PostHog `person_profiles: 'identified_only'`** so anonymous visitors do not + create person profiles. +- **No secrets committed.** Keys are provided only through build-time env vars. diff --git a/mkdocs.yml b/mkdocs.yml index 228c019..fbccea9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,6 +19,9 @@ copyright: >- theme: name: material + # Register the local overrides directory so overrides/main.html can inject the + # PostHog snippet and shared analytics event layer via the extrahead block. + custom_dir: overrides logo: assets/logo.svg favicon: assets/favicon.ico # Match the public site's local system stacks and avoid a third-party font @@ -85,6 +88,19 @@ markdown_extensions: extra: generator: false + # Analytics. See ANALYTICS.md (repo root) for the full data-handling notes. + # Google Analytics is env-driven; the fallback keeps the existing measurement + # ID working when GOOGLE_ANALYTICS_KEY is unset. GA measurement IDs are public + # (non-secret), so committing the fallback is fine. + analytics: + provider: google + property: !ENV [GOOGLE_ANALYTICS_KEY, "G-CJ01Y19XJN"] + # PostHog is read at BUILD time. When NEXT_PUBLIC_POSTHOG_KEY is unset (local + # builds and CI), posthog_key is "" and overrides/main.html emits no PostHog + # script at all. Reuses the same env var names and host as the marketing site + # so every property reports into one PostHog project. + posthog_key: !ENV [NEXT_PUBLIC_POSTHOG_KEY, ""] + posthog_host: !ENV [NEXT_PUBLIC_POSTHOG_HOST, "https://us.i.posthog.com"] social: - icon: fontawesome/brands/github link: https://github.com/OpenAdaptAI diff --git a/overrides/main.html b/overrides/main.html new file mode 100644 index 0000000..18af438 --- /dev/null +++ b/overrides/main.html @@ -0,0 +1,130 @@ +{% extends "base.html" %} + +{# + Privacy-safe analytics for docs.openadapt.ai. + + Google Analytics is wired through Material's native `extra.analytics` block + (see mkdocs.yml), which already handles pageviews and the built-in `search` + event, including under `navigation.instant`. This partial adds PostHog and a + small shared-taxonomy event layer on top. + + The PostHog script is emitted only when NEXT_PUBLIC_POSTHOG_KEY is present at + BUILD time (mkdocs `!ENV` substitution). When the key is unset (local builds + and CI), the entire PostHog block is absent from the generated HTML: a hard + no-op, not a disabled runtime path. +#} +{% block extrahead %} + {{ super() }} + + {% if config.extra.posthog_key %} + + + {% endif %} + + + +{% endblock %}