feat(marketing): add /mobile landing page behind the mobile-launch flag

Merged
KI
2mo ago
+1827-19

Summary

  • Adds superset.sh/mobile: a phone showcase, App Store and Google Play badges, a QR code for desktop visitors, and a waitlist.
  • Gates it behind a new PostHog flag, mobile-launch, so it ships dark and goes live on launch day (2026-09-21) without a deploy.
  • Once launched, links the page from the Product menu, the footer, the sitemap, and the /download Mobile card.

Why / Context

The iOS app is on the App Store, but the site has nowhere to send people for it, and the launch post (merged hidden in #7611) links to /mobile#android. Android is not out yet, so the page has to say that and still capture interest.

How It Works

  • Launch flag. FEATURE_FLAGS.MOBILE_LAUNCH lives in shared constants so other surfaces can key off the same launch. The marketing site evaluates it server-side with posthog-node, once for the whole site (fixed distinct id, cached 60s) rather than per visitor. That is what lets it gate the sitemap and page metadata, and it keeps pages from calling PostHog on every request. Any failure reads as off. The layout hands the value to the client header, footer and /download card through MobileLaunchProvider.
  • Flag off (what ships): no Product-menu, footer or sitemap entry; the /download Mobile card stays "Coming soon"; /mobile is noindex, both badges read "Coming soon to", there is no App Store link or QR code, and the waitlist is generic (platform: "ios").
  • Flag on: App Store badge links to the listing, the QR code encodes COMPANY.APP_STORE_URL (rendered to SVG with uqr, hidden below md), and the waitlist becomes the Android one (platform: "android"). Both record waitlist_signup in PostHog, the same path the Windows/Linux waitlist uses.
  • Phones are drawn in code, like the /download mocks, so the page never pins an app version or real workspace names. Side phones show below lg and from xl up; between them there is only room for one.
  • Store badges are drawn in code. Each label is one Lingui message with two tagged spans, so locales like Japanese can put the store name first.
  • mobile is now a reserved leaderboard handle. Without it, proxy.ts rewrites /mobile to a profile lookup and the route 404s. reserved-handles.test.ts enforces this for every marketing route.
  • 20 new strings, translated in all 16 non-English locales.

Manual QA Checklist

Checked on the dev server.

  • Flag off (real PostHog call, flag absent/disabled): /mobile is noindex with no App Store link; no /mobile link on the homepage or /download; no sitemap entry
  • Flag on (helper forced locally, then reverted): App Store link, QR code, site link and all 17 localized sitemap entries return
  • /mobile renders at 1440, 1280, 1024 and 390px with no horizontal scroll
  • /ja/mobile and /fr/mobile render; French (longest labels) keeps both badges on one row at 390px
  • App Store badge and QR code open the listing on a real iPhone (after launch)
  • Waitlist submit lands in PostHog

Testing

  • bun run typecheck in apps/marketing, packages/shared, packages/trpc
  • bunx biome check apps/marketing packages/shared/src packages/trpc/src/router/leaderboard
  • bun test in apps/marketing (141 pass, including a new sitemap test covering both flag states) and reserved-handles.test.ts
  • bun run check:i18n (0 missing in every locale), bunx sherif

Design Decisions

  • PostHog flag rather than a code constant: launch needs no deploy, and other surfaces can share the flag.
  • Evaluated per site, not per visitor: keep mobile-launch a plain on/off flag. A percentage rollout would hash the site's single distinct id to one side and never change.
  • Coded App Store badge instead of Apple's official artwork: the official badge bakes its wording into the image, so localizing it meant one SVG per locale plus a width table, with no Czech artwork at all. Swapping it in later only touches StoreBadges.tsx.
  • No "email me the link": the QR code serves the same desktop visitor.

Rollout

  • The mobile-launch flag already exists in the Production PostHog project, disabled. Merging changes nothing visible.
  • Launch day: enable the flag, and remove draft: true from the launch post.
  • The mobile handle was checked against production before merge: superset.sh/mobile returned 404, so no existing profile is displaced.
  • Rollback: disable the flag, or revert the PR. No data or schema changes.

Summary by CodeRabbit

  • New Features
    • Added a Superset Mobile marketing page featuring app previews, key benefits, App Store download options, QR code access, and mobile waitlists.
    • Added conditional navigation and download links based on mobile availability.
    • Added responsive messaging for iPhone availability and Android notifications.
  • Localization
    • Added mobile app, download, waitlist, and feature translations across supported languages.
  • Bug Fixes
    • Improved sitemap behavior so mobile pages appear only when available.
    • Reserved “mobile” as a protected route handle.