Skip to content

feat(analytics): track code copies and CTA views in PostHog#35

Open
coderdan wants to merge 1 commit into
mainfrom
feat/code-copy-cta-analytics
Open

feat(analytics): track code copies and CTA views in PostHog#35
coderdan wants to merge 1 commit into
mainfrom
feat/code-copy-cta-analytics

Conversation

@coderdan

Copy link
Copy Markdown
Contributor

Summary

Adds PostHog instrumentation to documentation code blocks so we can see which examples and calls-to-action drive engagement. PostHog was already wired up in the repo (src/lib/posthog/provider.tsx); this plugs into it.

Two events:

  • code_copied — fires on every code block's copy button click.
    • Properties: page_path, example_id, language, is_cta, and cta_type (only when is_cta).
  • cta_viewed — fires once when a block tagged as a CTA scrolls into view (IntersectionObserver, disconnects after firing).
    • Properties: page_path, example_id, cta_type.

Together these give a per-page cta_viewedcode_copied (is_cta: true) funnel — what % of people who see a CTA actually copy it.

How it works

  1. Build-time (source.config.ts): a Shiki transformer stamps every rendered <pre> with data-language, plus data-example-id / data-cta / data-cta-type / data-filename parsed from the code-fence meta string. It appends to Fumadocs' default transformers (so notation highlight/diff/focus keep working) and reuses rehypeCodeDefaultOptions.
  2. Client (src/components/code-block.tsx): TrackedCodeBlock overrides the pre MDX component. It leaves Fumadocs' code block (highlighting, copy logic, tabs) untouched and uses event delegation on the <figure> for the copy click, plus an IntersectionObserver on the same <figure> for the CTA view. Both events resolve example_id through the same helper, so they join up.
  3. Wiring (src/mdx-components.tsx): pre: TrackedCodeBlock.

Authoring syntax

```bash cta cta-type="install" example-id="install-drizzle"

  • example-id — stable slug (falls back to filename/language + position when omitted).
  • cta — sets is_cta: true and enables cta_viewed.
  • cta-typeinstall / quickstart / signup.

Annotated the primary install CTAs: drizzle, dynamodb, prisma-next, nextjs identity, supabase, stack migration. Documented in CLAUDE.md.

Validation

  • bun run types:check
  • bun run lint (changed files) ✓
  • bun run build ✓ — verified the prerendered HTML carries data-language on all blocks and data-cta/data-cta-type/data-example-id on annotated CTAs, with the copy button (aria-label="Copy Text") inside each <figure>.

Notes

  • Reuses the existing data-cta* attributes rather than a parallel data-posthog-* set, so example_id matches exactly between the two events (which is what makes the funnel join).
  • Unrelated: filename="…" on fences currently renders no title bar (Fumadocs maps title, not filename) — pre-existing, not touched here; the analytics fallback handles it.

Instrument documentation code blocks with PostHog so we can measure which
examples and calls-to-action drive engagement.

- A build-time Shiki transformer (source.config.ts) stamps each rendered
  <pre> with data-language plus optional example-id/cta/cta-type/filename
  parsed from the code-fence meta string.
- A TrackedCodeBlock client component overrides the `pre` MDX component and:
  - fires `code_copied` (page_path, example_id, language, is_cta, cta_type)
    on every copy-button click via event delegation, reusing Fumadocs' copy
    logic;
  - fires `cta_viewed` once when a CTA block scrolls into view via
    IntersectionObserver, forming a per-page cta_viewed -> code_copied funnel.
    example_id is resolved identically for both events so they join up.
- Annotate the primary install CTAs (drizzle, dynamodb, prisma-next, nextjs
  identity, supabase, stack migration) with cta metadata.
- Document the fence-metadata authoring syntax in CLAUDE.md.
@vercel

vercel Bot commented Jun 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
public-docs Ready Ready Preview, Comment Jun 30, 2026 7:54am

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant