Skip to content

feat(onboarding): extension showcase experiment on the extension step - #6679

Open
tsahimatsliah wants to merge 7 commits into
mainfrom
claude/extension-install-modal-review-a96e56
Open

tsahimatsliah wants to merge 7 commits into
mainfrom
claude/extension-install-modal-review-a96e56

Conversation

@tsahimatsliah

@tsahimatsliah tsahimatsliah commented Sep 17, 2026

Copy link
Copy Markdown
Member

What

Behind onboarding_extension_showcase (default off), the onboarding funnel's extension step swaps the explainer and demo video for a feature showcase that mirrors the product tour on the daily.dev homepage:

  • funnel headline
  • a caption that changes per feature
  • a centred tab carousel (selected tab in the middle, the rest fanning out behind faded edges)
  • an illustrated stage with the feature's ambient glows
  • the existing glass "Add to Chrome" CTA

Control keeps the current step untouched.

showcase

Features

Only what the extension adds on top of the web app, with the new-tab feed in the middle so the carousel opens on it: Read it here · Daily brief · Most visited · Shortcuts · New tab feed · Companion · Reading streak · Focus mode.

The feed plays cloudinaryOnboardingExtensionVideo (the clip the step already uses). The other seven illustrations live in packages/webapp/public/app/assets/extension-showcase/ and load through fromCDN, the same way HackathonHero loads its cover; Storybook maps that directory so the same paths resolve there. Four are captured from the homepage tour, four (Most visited, Shortcuts, Companion, Focus mode) are built in the same visual language from the real product surfaces.

Tracking

Tabs carry data-funnel-track={FunnelTargetId.ExtensionFeature}, so the funnel logs click funnel element with the feature label, alongside the existing download extension event.

Layout

The stage is sized from the viewport height (clamp(40rem, (100dvh - 30rem) * 2.04, 64rem)) so the whole step fits on 1440×900 and 1024×768 laptops without scrolling; on shorter screens it bottoms out at the video's width and the sticky CTA stays on screen.

Verification

  • FunnelBrowserExtension.spec.tsx: flag off renders the video step, flag on renders the showcase.
  • ExtensionShowcase.spec.tsx: default selection, caption and illustration swap.
  • Storybook: Components/Onboarding/Steps/BrowserExtension showcase (showcase, control, and a four-resolution comparison), Components/Onboarding/ExtensionShowcase (component playground).
  • Strict typecheck, shared lint, onboarding suites, webapp tsc and webapp tests pass.

Notes

  • The flag is off by default, so the Vercel preview shows control; pin it in GrowthBook (or review in the Storybook deploy) to see the variant.
  • The "Daily brief" caption ("Your first tab of the day opens to an AI brief") is the homepage tour's wording; it is not something the extension does today.

🤖 Generated with Claude Code

Preview domain

https://claude-extension-install-modal-r.preview.app.daily.dev

@vercel

vercel Bot commented Sep 17, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
daily-webapp Ready Ready Preview Sep 17, 2026 3:26pm UTC

Request Review

Behind onboarding_extension_showcase (default off) the onboarding funnel's
extension step swaps the explainer and demo video for a feature showcase:
the funnel headline, a caption that changes per feature, a centred tab
carousel and an illustrated stage, mirroring the product tour on the daily.dev
homepage. Control keeps the current step untouched.

The eight features are only what the extension adds on top of the web app,
with the new-tab feed in the middle so the carousel opens on it and plays the
same new-tab video the step already uses. The other seven illustrations are
served from the webapp's public assets through fromCDN, and Storybook maps
that directory so the same paths resolve there.

Tabs carry data-funnel-track with a new FunnelTargetId.ExtensionFeature, so
the funnel logs which feature was clicked alongside the existing download
event for the experiment's analysis.

Mockup-to-eng-pass: 1

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…lves

Painting the video step and swapping to the showcase when the flag landed
showed the control arm to treatment users first, so the body now waits for
the flag the way the hero step does, capped at 200ms in case boot returned
no experiment features. The showcase also renders nothing for an empty
feature list instead of throwing, and re-centres the selected tab once web
fonts settle the pill widths.

Mockup-to-eng-pass: 1

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@rebelchris rebelchris left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Flag-gated (onboarding_extension_showcase, default false) swap of the onboarding extension step's explainer + demo video for a tab carousel and illustrated stage. Control markup is preserved verbatim, the step stays laptop-only via useOnboardingExtension, tracking reuses the existing data-funnel-track capture (so target_id lands as the tab's innerText, i.e. the feature label — that part checks out), and there are tests for both arms plus Storybook coverage at four laptop resolutions. Scope is clean: every file belongs to the variant.

Two things I would want resolved before this goes to a real cohort, plus some non-blocking notes. Details are inline.

Blocking

  • defaultFeatures.ts — the "Daily brief" caption promises behaviour the extension does not have.
  • FunnelBrowserExtension.tsx — the 200ms flag-hold changes the control arm and does not actually close the flash it targets.

Non-blocking — manual scroll centering vs scrollIntoView, tab-set semantics/keyboard, illustration preloading, and the cross-repo duplication of the tour data.

Verification

  • Read root AGENTS.md/CLAUDE.md and traced the step's guards (withShouldSkipStepGuardshouldShowExtensionOnboarding is isLaptop-gated, so phone layouts are genuinely out of scope here)
  • Control arm compared against main markup
  • Analytics path traced through useFunnelTracking's trackOnMouseCapture
  • Existing primitives searched (components/tabs/TabContainer, containers/Carousel)
  • CI inspected (all green except test_shared/build still running at review time)
  • Not verified: the live preview with the flag pinned on, at 1024×768 and 1440×900

Reviewed by AI.

Comment thread packages/shared/src/components/onboarding/ExtensionShowcase/defaultFeatures.ts Outdated
Comment thread packages/shared/src/features/onboarding/steps/FunnelBrowserExtension.tsx Outdated
Comment thread packages/shared/src/components/onboarding/ExtensionShowcase/ExtensionShowcase.tsx Outdated
Comment thread packages/shared/src/components/onboarding/ExtensionShowcase/ExtensionShowcase.tsx Outdated
The 200ms flag hold gated the body for every onboarding user, so control
rendered an empty step on mount; an unresolved flag now falls through to
control untouched, which is also what the step sits deep enough in the funnel
to always get. The "Daily brief" caption promised a first-tab brief the
extension does not open; it now describes the brief itself.

The carousel is a real tab set (tablist/tab/tabpanel, aria-selected, roving
tabindex, arrow/Home/End keys, live caption) instead of a nav of toggles,
centres the selected tab with scrollIntoView, honours prefers-reduced-motion,
and warms every illustration up on mount so the first click on a tab does not
show an empty stage.

Mockup-to-eng-pass: 1

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@rebelchris rebelchris left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review of 2157d95

Both blockers are properly resolved, not papered over.

  • Control armhasWaitedForFlag/FLAG_RESOLVE_TIMEOUT_MS are gone and the unresolved flag falls through to control, so with the flag off the step is byte-identical to main again. Diffed it against main to confirm. Thanks for saying plainly that nothing was observed behind the hold; that is the right call.
  • Copy — the brief caption no longer claims the first tab of the day auto-opens a brief, and it matches what the illustration shows.
  • The three non-blocking items are all addressed, and the ownership/refresh story for the tour content is now recorded in the code comment rather than only in the thread.

CI is fully green on this commit.

The tab-pattern rewrite is the right shape and the keyboard coverage is good, but it picked up four small things on the way in — all non-blocking, two of them mean the a11y fix does not fully land at runtime. Details inline. I would not hold the experiment for them if you would rather fix them in a follow-up; say which and I am happy with either.

Verification

  • Control render diffed against main
  • Flag-loading path re-traced through useConditionalFeature
  • New tests read (arrow/Home/End, reduced motion, preload, flag-loading-renders-control)
  • CI green: test_shared, test_webapp, test_extension, lint_shared, typecheck_strict_changed, build
  • Still not verified by me: the live preview with the flag pinned on, and a screen-reader pass over the new tab set

Reviewed by AI.

Comment thread packages/shared/src/components/onboarding/ExtensionShowcase/ExtensionShowcase.tsx Outdated
Comment thread packages/shared/src/components/onboarding/ExtensionShowcase/ExtensionShowcase.tsx Outdated
Comment thread packages/shared/src/components/onboarding/ExtensionShowcase/ExtensionShowcase.tsx Outdated
The tablist role sat on the scroll container with a layout div between it
and the tabs, so the tree had no tabs to count; the role now sits on the row
that holds them. The live caption region is a stable wrapper so the keyed
caption inside it is announced, the illustration panel takes focus since it
holds nothing focusable, arrow-key focus moves without the browser's own
scroll so the effect centres once, and the preload runs once per set of
sources rather than per render.

Mockup-to-eng-pass: 1

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

2 participants