Skip to content

PostHog playbook ​

This is the copy-pasteable version of "how do I turn Spotlight events into useful product-analytics views in PostHog". Every event name and property below is emitted by the SDK unchanged — build dashboards against them and SDK upgrades won't break your definitions.

1. Wire up forwarding ​

Two prerequisites on your page:

  • The PostHog JS SDK loaded with your project API key (the usual posthog.init(...) snippet — nothing Spotlight-specific).
  • In Spotlight: Dashboard → Analytics → PostHog toggled on.

That's it. On the next SDK config refresh (≤ 30s TTL) the Spotlight SDK starts calling window.posthog.capture(name, props) for every event alongside its own backend writeback. No extra network hop from Spotlight — PostHog sees events at the same latency as your own.

Verify it's live

Open DevTools → Network, filter for /e/ (PostHog's event endpoint), trigger a tour, and watch the spotlight.tour_started event fly past. If you see Spotlight events on the Spotlight backend but not in PostHog, your PostHog SDK isn't loaded on that page.

2. Identify your users ​

PostHog funnels only stitch a journey together when events carry the same distinct_id. Two rules:

  1. Call posthog.identify(user_id, props) as soon as your app knows who the user is — typically on login / session boot.
  2. Pass the SAME user_id to Spotlight.init({ userId }).

If both use the same id, Spotlight events and your product events sit on one timeline in PostHog. If they diverge, your Spotlight events land on anonymous distinct_ids and funnels miss the later steps.

js
posthog.identify(currentUser.id, { plan: currentUser.plan });
Spotlight.init({
  apiKey: 'sk_live_…',
  userId: currentUser.id,
  tokens: { plan: currentUser.plan },
});

3. Canonical event names ​

Stable across SDK versions. Dashboards built against these names survive upgrades.

EventFires when
spotlight.impressionAny piece of content rendered on screen
spotlight.clickNon-CTA click registered on content
spotlight.cta_clickedPrimary CTA (tooltip / modal / banner / hotspot)
spotlight.dismissedUser closed content (X, Escape, backdrop)
spotlight.tour_startedTour opened (welcome page or step 1)
spotlight.tour_step_viewedTour advanced to a new step
spotlight.tour_completedUser reached the finish page
spotlight.tour_skippedUser closed the tour before finishing
spotlight.hotspot_expandedHotspot card opened

Every event carries content_id (tour / content identifier) plus event-specific props such as step_index, url_path, target (selector), and elapsed_ms since the previous step.

4. Insights to copy ​

4a. Tour completion funnel ​

Goal: "of users who started tour X, what % finished each step?"

  • Type: Funnel
  • Steps (in order):
    1. spotlight.tour_started with property content_id equals <your_tour_id>
    2. spotlight.tour_step_viewed with property content_id equals <your_tour_id> and step_index equals 1
    3. spotlight.tour_step_viewed with property content_id equals <your_tour_id> and step_index equals 2
    4. (one row per step)
    5. spotlight.tour_completed with property content_id equals <your_tour_id>
  • Conversion window: 1 day (or one session — use whatever matches the tour's purpose)
  • Attribution: First touch

This is the single most useful view. "Step 3 → step 4 drops by 60%" is a concrete signal that step 3's body is too long or step 4's target is too hard to find.

4b. Drop-off by step (trend, not funnel) ​

Useful when you've got a multi-tour product and want a bird's-eye view of where tours bleed out.

  • Type: Trends
  • Event: spotlight.tour_skipped
  • Breakdown by property: step_index
  • Filter: content_id in […your tour ids…]
  • Chart: Bar (cumulative)

4c. CTA click-through by page ​

Which pages' tooltips / modals actually convert?

  • Type: Trends
  • Events (two series):
    1. spotlight.impression, breakdown by url_path
    2. spotlight.cta_clicked, breakdown by url_path
  • Formula: B / A — click-through rate per URL
  • Sort descending. Low CTR on a high-traffic URL is the first thing to rewrite.

4d. Tour completers retention ​

Do users who finish a tour retain better than those who skip?

  • Type: Retention
  • Target event: spotlight.tour_completed (cohort)
  • Returning event: any product event that means "used feature X"
  • Comparison cohort: spotlight.tour_skipped

If the two lines are the same, your tour isn't teaching anything — either the feature is obvious or the tour missed the mark.

5. Dashboard layout ​

One dashboard per tour, three tiles:

  1. Completion funnel (insight 4a).
  2. Impressions per day — Trends on spotlight.impression, filter content_id equals your tour. Tells you whether the tour is even reaching enough people.
  3. Weekly completers vs skippers — two trend series, spotlight.tour_completed and spotlight.tour_skipped. Ratio over time is your "is this tour getting better or worse".

6. Gotchas ​

  • PostHog feature flags apply to Spotlight events too. If you route spotlight.* to a session-recording mute, recordings stop. Usually what you want; note it.
  • Anonymous → identified merging: PostHog merges anon sessions on identify, but only if your product SDK calls identify before Spotlight fires. The SDK's auto-start may emit events before your login round-trip completes; pass autoStart: false in Spotlight init if you need a strict order.
  • GA4 receives the same events, mangled. GA4's event-name rules are stricter (no dots, 40-char cap), so events land as spotlight_tour_step_viewed. PostHog is unaffected.

Last updated:

Spotlight