Standalone routes: what's left after monetize and home Profile

All nine steps of this plan are done. Steps 1 to 7 are merged, in PRs 10837, 10838 and 10839. Steps 8 and 9 are merged in PR 10840. SharedModule is deleted, and none of the lazy entry points loads it, down from 39 at base. PR 10841 deleted DynamicFormBuilderModule, the last feature NgModule. PR 10842 made the unused BioLinkPipe standalone. PR 10845 deleted leftover unused components. PR 10847 is merged. It splits monetize child routes, keeps ProfileComponent off the main home chunk, and lazy-opens the post-price camera modal. The public marketing layouts now load with import(). Notes are in public marketing pages load only the layouts they use. What is still optional is in leftovers after the SharedModule work.

base hotfix/release-0.0.23/21-code-refactors at 33fcd8d508 branch t3code/lazy-marketing-layouts at 3645b6d5ee sizes from the QA build, 25 Sep 2026 plain version

Where things stand

The merged PRs came before this plan. The steps below are grouped into PRs. Each has its own doc with what changed, how it was checked, and a checklist for manual testing.

ChangeStatusWhat it did
10826mergedFive single-component feature modules became standalone routes.
10828mergedRemoved withComponentInputBinding(), which was wiping input defaults.
10829mergedadvertisement-home, global, and marketing-pro-page became standalone.
10830mergedThe 15 one-component public pages became standalone.
10831mergedThe 10 mid-sized modules became standalone. The route leaks under /resources, /auth, /insights, and /messages went with them.
10832mergedSharedModule left the initial bundle. Initial JS went from 10.09 MB to 6.86 MB.
10833mergedWallet became standalone and stopped loading SharedModule. /wallet went from 4.05 MB to 1.68 MB of lazy JS.
10837, step 1, 81797c0569mergedThe 18 small pages stopped loading SharedModule.
10837, step 2, 0beb9e0e04 and dd02f5c329mergedMarketingPageSharedModule's 55 components became standalone. The home, marketing and search pages stopped loading SharedModule.
10837, step 3, 96be9f8389mergedMonetizeModule is gone. /monetize loads a routes file and stopped loading SharedModule, apart from portfolio.
10837, step 4, b0114afffdmergedAuth, forum, resources, messages, insights and post detail stopped loading SharedModule.
10838, steps 5 and 6, 00a1edbc5c, ae40c39204 and 9897f212fdmergedLink in bio stopped loading SharedModule. ProfileModule and PortfolioModule are gone, and portfolio's routes no longer leak into /dashboard.
10839, step 7, 56a5ec11eb and e92a285200mergedEditPreferenceModule and WhitelabelCoverPageModule are gone, and neither route loads SharedModule.
10840, steps 8 and 9, 26235a170b, d1184365be, 7d1763c28f and 7c0b9351acmergedDashboardModule, SharedModule and MarketingPageSharedModule are gone.
10841, 5bdbb26936 and 643b28fbfamergedDynamicFormBuilderModule is gone. Its 92 importers take only the pieces they render.
10842, 27d6a631e0mergedThe unused isLink pipe is standalone. Profiles already used a different BioLinkPipe.
10845, c928ecc3f1 and ad0fff9aafmergedUnused leftover components are deleted. seo-landing.model.ts and the store item card stay.
10847, 3e564a2ca2, 367e633593, 6db341b485 and cb2893c092mergedMonetize children use loadComponent. Main / no longer bundles ProfileComponent. The post-price camera modal loads on click.
10849, 3645b6d5eeopenPublic marketing pages load only the layout ids they show. Header stays static. The editor still ships the catalog.

Lazy JS, base against now

What a first visit fetches after the initial bundle. Base is 16a5786e9c and now is 3645b6d5ee. Marketing rows after 10847 were 1.23 to 2.05 MB. Home after 10847 was 2.79 MB. MB means a million bytes.

RoutesBaseNowLoads SharedModule now
18 small pages. /about, /pricing, /contact-us, /explore-creators, /not-found and the rest3.31 to 3.42 MB0.00 to 0.79 MBNo
Home. / and /home/:catName4.43 MB1.76 MBNo
Marketing. The marketing, comparison, and pro pages4.39 to 4.41 MB0.03 to 0.86 MBNo
Sub-pages and creators-home4.40 to 4.45 MB0.11 to 0.21 MBNo
/monetize, apart from portfolio5.36 MB12.7 KB parent, then the pageNo
/auth, /forum, /resources3.39 to 3.50 MB0.81 to 0.98 MBNo
/messages, /insights, /post3.73 to 5.41 MB1.85 to 2.70 MBNo
Link-in-bio pages5.21 MB1.20 MBNo
Creator profiles, /:id and /wls/:id3.31 MB1.85 MBNo
/monetize/portfolio5.06 MB2.06 MBNo
/edit-preference7.39 MB4.31 MBNo
The whitelabel cover page5.28 MB3.15 MBNo
/dashboard6.42 MB5.09 MBNo

The initial bundle is 4.1 KB smaller than base. The last 3.2 KB of growth is more lazy entries, 81 instead of 49, after monetize pages, ProfileComponent, and the camera modal became their own files. The build has 341 JavaScript files, up from 114 at base.

What's left

No route loads SharedModule, and with PR 10841 no feature NgModule is left. Optional leftovers, and what I would do with each, are in leftovers after the SharedModule work.

What the steps taught

  • The first count missed standalone components that still import SharedModule. In step 3, /monetize kept loading it through the text editor, its AI modal and the post price dialog. Step 4 was meant to be import swaps only and needed nine conversions. The table above now counts those files too.
  • My conversion script moved a declaration to imports only when a comma followed it, so it missed the last entry twice. That's fixed, and it now works on any NgModule file.
  • A module's CUSTOM_ELEMENTS_SCHEMA can hide dead bindings. Portfolio's hid four [infoIconSize] bindings on a component with no such input, and edit preference's hid a [socialHandles] binding. Dashboard's hid a [coverImage] binding on the video player.
  • A module's providers need a new home when the module goes. Edit preference provided DatePipe for one page, so that page provides it now. Dashboard gave itself its own DashboardModuleService, which holds state, so its providers moved to its top-level route. That keeps a separate instance, like the lazy module did.
  • Providers the old module got from an imported module count too. Dashboard got isPostCollaboratorPipe from SharedModule, and that pipe reaches DashboardModuleService through MyProfile. So it went on the dashboard route as well.
  • A diff that ignores too much can hide a regression. The form builder component lost five field components on the first try, because the diff filter skipped more than the one directive it was meant to. The diff script now ignores only that directive, and a rerun on PR 10840 found nothing new.
  • An NgModule that nothing imports drops out of the compile. Once dashboard stopped importing SharedModule, its remaining declarations compiled with no template scope. So they had to become standalone first.
  • Importing a whole feature module into another also imports its routes. Portfolio's 26 routes were reachable under /dashboard until step 6.
  • The test account is a white-label creator, so creator pages only open on a white-label build. The main site sends creators to /edit-preference/whitelabel. Logged-in checks from step 3 on ran on a white-label build.
  • /messages sometimes throws "Cannot read properties of undefined" when the QA API is slow. It happens on base too.

Suggested PRs

PR 10837 had steps 1 to 4, PR 10838 had steps 5 and 6, and PR 10839 had step 7. PR 10840 had steps 8 and 9. All four are merged. PR 10841 did the form builder. PR 10842 did the leftover pipe. PR 10845 deleted unused leftovers. PR 10847 did the monetize, home-profile, and camera follow-ups. The layout split is the leftover after that.

  1. The 18 small pages done

    PR 10837. Every page dropped to 0.81 MB or less.

  2. Home and marketing pages done

    PR 10837. / went from 4.43 MB to 3.23 MB, and creators-home from 4.45 MB to 1.30 MB.

  3. Monetize done

    PR 10837. It needed 11 SharedModule pieces, and three standalone components had to stop importing it.

  4. Auth, forum, resources, messages, insights, and post done

    PR 10837. It needed four SharedModule pieces and the four portfolio music components.

  5. Link in bio and profile done

    PR 10838. Link in bio went from 3.82 MB to 1.20 MB with four import swaps. Profile went from 3.35 MB to 1.86 MB, with no conversions needed elsewhere.

  6. Portfolio done

    PR 10838. /monetize/portfolio went from 5.10 MB to 2.07 MB, and /dashboard from 6.46 MB to 5.66 MB. The leaked routes under /dashboard are gone.

  7. Edit preference and the whitelabel cover page done

    PR 10839. /edit-preference went from 6.03 MB to 4.33 MB, and the cover page from 5.29 MB to 3.18 MB. It needed two SharedModule pieces. DynamicFormBuilderModule stays an NgModule for now.

  8. Dashboard done

    PR 10840. /dashboard went from 5.65 MB to 5.10 MB. It needed 18 SharedModule pieces, including OrderConfirmationComponent, which it routes to, and WatermarkControlsComponent.

  9. SharedModule itself done

    PR 10840. Its last 27 declarations became standalone before dashboard dropped it, and then it was deleted. MarketingPageSharedModule went too. The marketing and comparison pages went from 2.16 MB to 1.23 MB.

  10. The dynamic form builder done

    PR 10841. Its 18 components became standalone and its 92 importers take only what they render. Most routes got about 13 KB lighter.

  11. BioLinkPipe done

    PR 10842. The unused isLink pipe is standalone. The profile bioLink pipe already was.

  12. Unused leftovers done

    PR 10845. Deletes the unused SharedModule leftovers, the unused seo landing UI, the interests accordion, and three unused store item views.

  13. Monetize children, home Profile, camera modal done

    PR 10847. Subscriptions drop from 3.20 MB to 0.53 MB. Main / drops from 3.22 MB to 2.79 MB.

  14. Public marketing layouts open

    PR 10849, 3645b6d5ee. Marketing drops from 1.23 MB to 0.03 MB. Comparison drops from 1.23 MB to 0.03 MB. Home drops from 2.79 MB to 1.76 MB because promotional.routes still statically owns landing, detail, and search.

Each PR got the same checks. That means an AOT dependency diff against the previous step, QA and development builds, per-route lazy JS, a browser walk of component definitions, SSR compared against the previous step, logged-in runs on a white-label build, and ESLint on the changed files.

Smaller follow-ups

  • comparison-layout.utils imports the editor constants.
  • White-label cover pages still fetch ProfileComponent in the landing constructor.
  • The post-price leftover after dashboard is still custom-input-list sitting with add-lock, not unused decorator imports.
  • Four portfolio info icons were meant to be 18 pixels and have always been 16.
  • Some files these steps touched have console.log calls from before.