Target: apps/home-mobile async chunk → @staticpages/turbo-shared/btf
Source: static-pages rebrand only (home-rebrand/, rebrand/, pages/app/)
Future: apps/home-desktop imports the same export
Gist: https://gist.github.com/shakyShane/aab408f0552fe7d692970ef4ee64a060
Not a page architecture. One deliverable:
// home-mobile (today) and home-desktop (later)
import { BelowTheFold } from "@staticpages/turbo-shared/btf";
// inside existing dynamic(..., { ssr: false }) boundary:
<BelowTheFold variant="in-app" />;Everything else is staging work to get there.
packages/turbo-shared/src/btf/ ← new folder, sibling to components/, hooks/, utils/
index.tsx ← Stage 2: sole public export
below-the-fold.tsx ← wrapper component (origin, legacy hide, shell)
in-app/ ← mobile homepage variant (from home-rebrand)
promotional/ ← desktop promotional variant (future, not stage 1)
app-page/ ← extracted AppRebrand (from pages/[locale]/app)
sections/ ← download-options, product-showcase, compare table, FAQ, footer…
adapters/ ← bridge static-pages hooks → turbo-shared providers
assets/ ← favorite icons etc.
Add to packages/turbo-shared/package.json exports:
"./btf": "./src/btf/index.tsx"turbo-shared is already the shared delivery point for turbo apps. BTF belongs here — not a new package, not copies in home-mobile/src.
| Use | Path |
|---|---|
| ✅ | home-rebrand/in-app-home-below-the-fold.tsx and friends |
| ✅ | rebrand/product-showcase, rebrand/faq-section, rebrand/footer, etc. |
| ✅ | pages/[locale]/app/index.tsx (component only — strip page exports) |
| ❌ | components/pages/home/ legacy tree |
Import-graph from rebrand BTF roots: ~122 TS files (+ SCSS + PNG assets). Breakdown:
| Bucket | ~Files | Stage 1 action |
|---|---|---|
icons/ |
45 | Copy into btf/icons/ or symlink; icons are leaf deps |
rebrand/ + pages/app/ + components/pages/app/ |
~30 | Core section components |
utils/ + hooks/ |
~28 | Don't copy — wire to btf/adapters/ → existing turbo-shared |
stores/ + misc |
~19 | Copy or stub (atbStore only needed for app-page campaign id) |
Goal: Get real rebrand BTF rendering in home-mobile's async chunk. Accept messy internals. Learn what's missing.
Do not polish folder structure or API yet. Do get visual parity with static-pages /home/mobile scrolled to BTF.
- Create folder + minimal
index.tsxre-exporting a work-in-progress component - Add turbo-shared deps:
@staticpages/design-system,motion,classnames(already have), possibly@reach/visually-hidden - Add jest/webpack/svg handling if icons need it (mirror home-mobile's next config patterns for turbo-shared consumers)
Copy rebrand BTF subtree from static-pages into btf/ preserving relative structure enough to compile. Suggested copy order (all in one branch — order only matters for incremental debugging if build breaks):
in-app-home-below-the-fold.tsx+.module.scss+assets/icon*.pngdownload-options.tsx+ scssproduct-showcase.tsx+ chip + scssapp-page/— extractAppdefault export frompages/[locale]/app/index.tsx; copycomponents/pages/app/*- Follow broken imports — pull in
rebrand/compare-privacy-table,rebrand/download-panel,rebrand/faq-section,rebrand/footer,rebrand/addToBrowser/, etc.
Inside btf/ only, replace static-pages aliases:
| Was | Becomes |
|---|---|
@hooks useDevice |
btf/adapters/use-device.ts → re-export turbo-shared DeviceProvider hook |
@hooks useOrigin |
extend turbo-shared/utils/origin (add content segment + decorateOriginInUrl) |
@utils/pixel Pixel |
turbo-shared/utils/pixel |
@components/themedImage |
copy small component into btf/ or turbo-shared/components/ |
@icons/* |
btf/icons/ copies or shared icons package later |
@pages/[locale]/app |
btf/app-page/app-rebrand.tsx |
Leave // @intl-meta pragmas — they'll get picked up when home-mobile runs i18n:messages.
// page.tsx — keep existing dynamic boundary, change target only
const MobileBelowTheFoldIsland = dynamic(
() => import("@staticpages/turbo-shared/btf").then((m) => m.BelowTheFold),
{ ssr: false, loading: () => null },
);
// page.tsx render — thin shell stays in app
<MobileBelowTheFoldIsland
variant="in-app"
id={HOME_MOBILE_BELOW_THE_FOLD_ID}
testId="below-the-fold"
/>;Stage 1 BelowTheFold can be a thin rename of ported InAppHomeBelowTheFold + wrapper styles. Props minimal: variant, id, testId.
- home-mobile
#i18n:messages: addapp,add-to-browser,compare-privacy,compare-privacy-compact,homepage-faq - Run
npm run i18n:extractfrom root after porting strings turbo run dev --filter=home-mobile→ scroll pull-tab → compare against static-pages mobile
- BTF visually matches static-pages rebrand mobile (top heading, download options, chips, compare table, feature cards, FAQ, footer)
- BTF CTAs have
origin=…__details - No SCSS leaked into ATF inline CSS bucket (monolithic dynamic import preserved)
- Build + types pass
Stage 1 explicitly defers: clean internal folder layout, static-pages dedup, home-desktop, promotional variant, exhaustive tests.
Goal: BelowTheFold is the only import surface. Internals reorganized. Desktop-ready.
// packages/turbo-shared/src/btf/index.tsx
export { BelowTheFold } from "./below-the-fold";
export type { BelowTheFoldProps, BelowTheFoldVariant } from "./below-the-fold";
type BelowTheFoldVariant = "in-app" | "promotional";
type BelowTheFoldProps = {
/** Mobile homepage uses "in-app". Desktop promotional will use "promotional". */
variant?: BelowTheFoldVariant;
/** Scroll target for pull-tab. Mobile: "home-below-the-fold". Desktop may use "features". */
id?: string;
testId?: string;
/** Origin content segment. Default "details" → funnel_home_website__details */
originContent?: string;
className?: string;
};function BelowTheFold({ variant = "in-app", ...shell }: BelowTheFoldProps) {
return (
<BelowTheFoldShell {...shell}>
<OriginCustomizer content={shell.originContent ?? "details"}>
{variant === "in-app" ? <InAppContent /> : <PromotionalContent />}
</OriginCustomizer>
</BelowTheFoldShell>
);
}InAppContent= currentInAppHomeBelowTheFoldbodyPromotionalContent= portpromotional-home-below-the-fold.tsxwhen home-desktop needs it (Stage 2b)
Lives in below-the-fold.tsx, not in each app:
id/data-testidon outer<section>.belowTheFoldWrapperstyles (from rebrandminimal-homepage.module.scss)OriginCustomizerProvider(content=details)- Hide on
.is-legacy-device - DS motif side-effect imports (
mandarin,lilypad,pollen,pondwater)
Apps become trivial:
// home-mobile
<BelowTheFold variant="in-app" id="home-below-the-fold" testId="below-the-fold" />
// home-desktop (future)
<BelowTheFold variant="promotional" id="features" testId="belowTheFold" />- Reorganize dumped files into
sections/,app-page/,in-app/,promotional/ - Delete duplicate adapters; consolidate origin/pixel into turbo-shared proper
- Add
turbo-sharedunit tests forBelowTheFoldshell (origin decoration, legacy hide) - Add home-mobile integration tests (
assertBelowTheFoldorigin pattern) - Optional: rewire static-pages
home-rebrand/in-app-home-below-the-foldto import from@staticpages/turbo-shared/btf
- Only
@staticpages/turbo-shared/btfimported by turbo apps for BTF -
BelowTheFoldPropsdocumented and stable -
promotionalvariant implemented or stubbed with clear TODO for home-desktop - Tests for origin + visibility
| Approach | Risk |
|---|---|
| Design perfect package API first, then port | Spend days on structure before knowing what breaks (icons, origin, i18n subset, motion, atbStore, app redirect hooks) |
| Dump → look → contract | Stage 1 surfaces real integration gaps in 2–3 days; Stage 2 codifies what actually worked |
Stage 1 is deliberately allowed to be ugly inside btf/. The async chunk boundary in home-mobile already isolates it from ATF perf concerns.
page.tsx (sync)
HeroLayout + ATF components
dynamic(() => import('@staticpages/turbo-shared/btf')) ← async chunk
BelowTheFold
… all BTF SCSS + DS + motion …
Never import BTF modules synchronously in page.tsx. Never split BTF into multiple top-level dynamic imports unless each is SCSS-safe.
| Stage | Work | Time |
|---|---|---|
| 1a Scaffold + deps | turbo-shared btf/ folder, package.json exports + deps |
0.5 day |
| 1b–c Dump + rewire | Copy ~122 files, adapter pass, fix build | 2–3 days |
| 1d–e Wire + visual check | home-mobile import swap, i18n, side-by-side | 1 day |
| Stage 1 total | ~3–4 days | |
| 2 API + cleanup + tests + promotional stub | ~2–3 days | |
| Grand total | ~5–7 days |
| Decision | Choice |
|---|---|
| Package location | packages/turbo-shared/src/btf/ |
| Public export | @staticpages/turbo-shared/btf → BelowTheFold |
| Design | Rebrand only |
| Stage 1 variant | in-app only |
Legacy pages/home/ |
Out of scope |
Separate @staticpages/home-btf package |
No — use turbo-shared |
Run import-graph walk from these four files only:
apps/static-pages/src/components/pages/home-rebrand/in-app-home-below-the-fold.tsxapps/static-pages/src/components/pages/home-rebrand/download-options.tsxapps/static-pages/src/components/rebrand/product-showcase.tsxapps/static-pages/src/pages/[locale]/app/index.tsx
Stop at any path under components/pages/home/.