Walk this on a QA SSR build. A miss here is a 19 regression unless the last chapter says otherwise. What changed in the bump lives in Angular 15 to 19.
Boot this, not that
The build that ships
Put nvm Node 20.19.6 first. Machine default 24 will fight you. Then:
npm run prerender-all-qaPORT=4100 npm run serve:ssrThat is dist/TopFans/server/server.mjs after a qa prerender.
A qa --prerender=false build is fine for click-through. It is not the artifact you upload.
Skip as gates
npm run build-devis the wrong env and the wrong output shape.ng lintstill OOMs. It did that on 18.ng testhas no specs worth running.- Docker is not this list.
ng serve/node:startis Vite. Use it to poke HMR, not to sign off SSR.
What 19 actually moved
| Thing | Pass when |
|---|---|
| Angular | HTML has ng-version="19.2.25" |
| TypeScript / zone | 5.8.3 and 0.15.1 in package.json |
| CommonEngine | Import is @angular/ssr/node, not @angular/ssr |
| Hosts | server.ts and angular.json both list loopback plus *.topfan.dev / *.topfan.com |
| Components | NgModule decls carry standalone: false |
| Scripts | start is HMR-on. start:no-hmr exists. No dev:ssr, no start:hmr |
Held on purpose
server.tsstay
Do not swap in the CLI default server. White-label host picking lives here.
Hit Express first
v19 CommonEngine refuses hosts that are not on the allowlist and falls back to the CSR shell. That looks like a 10ms empty page. Fix the allowlist, then click product.
/login/is 301 to/login- Query string survives
- Garbage URL is HTTP 404
- Not a 200 blank shell
/creators?key=is live SSR- Not a prerender page that dropped the key
- curl
127.0.0.1must be fat HTML - Empty 119k shell means hosts
After prerender, both dist/TopFans/browser/index.html and index.csr.html exist. Live SSR uses the CSR file as the engine document.
Public pages that must still render
| Path | Pass when |
|---|---|
/auth/login | Form chrome is there. Submit success is not the gate. |
/auth/forgot-password | Same. Page paints. |
/pricing | Plans show. No empty layout. |
/about | Copy and layout survive. |
/music | Browser lands on /music-artists. |
/wallet while logged out | AuthGuard sends you to login. That is success. |
Logged-in money and media
These need a real session. Compile-green is not a pass.
| Check | Pass when |
|---|---|
| Home feed | Posts load. Like, comment, share on a normal post still open the old bootstrap/ng-bootstrap modals, not a crash. |
| Wallet | Current balance paints. Masked phone / amount fields still take keystrokes. |
| Create Plan | Name + benefit + open 1 Month + a Total Price of 1 or more enables Create Plan. Empty price stays disabled. That disable is old. Do not file it. |
| Stripe | A test payment or Connect flow completes. Package is still ngx-stripe 18. |
| Audio | A portfolio track plays. Player stayed on 17. |
| Video | A video.js or IVS post plays. Close and reopen is not a dead player. |
| Phone inputs | ngx-intl-tel-input 15 country dropdown still works on contact or personal info. |
| Toasts | A success and an error toast still appear and dismiss. ngx-toastr 19 made them OnPush. |
Reels sheets are the Material 19 path
Angular Material in this app is only MatBottomSheet. It mounts on a reel at viewport ≤992px. Desktop tip / likes / share are ngx-bootstrap or ng-bootstrap. Those still inject Material tokens, so open them once on a wide window to prove they do not throw.
Log in. Open a reel. Narrow the window. You want the full-screen reel chrome with like, comment, tip, share on the right.
| Icon | Pass when |
|---|---|
| Comments | Sheet opens with the current reel's comments. Close, swipe to the next reel, open again. Data matches the new reel. |
| Likes | List of likers. Scroll stays inside the sheet. |
| Tip | Amounts work. Cancel closes with no charge. Confirm still pays. |
| Share, logged in | Copy link / share options. Close dismisses. |
| Share, logged out | Login modal. Not a blank sheet. |
The sheet will look a bit wrong
- Look
- White padding around a dark comments panel. Square top corners. Default Material chrome instead of the 24px radius and
#002740fill. - Cause
- Our CSS still targets
.mat-mdc-bottom-sheet-container. Material 19 renamed the host to.mat-bottom-sheet-container. Overlay sits onbody, so theme-nested rules miss it too. - Call
- File it as known 19 chrome, not as "comments are broken." Open, list, dismiss, next-reel data. If those work, the feature works. Restyle later.
Do not "fix" it by adding a /.well-known JSON file. That was a Vite overlay hack, reverted, and it does not belong in prerender output.
One white-label tenant
Generator copies TopFans build config, then stamps the tenant theme. Prove one QA tenant. Restore generator artifacts. Do not commit them, and do not commit environment.ts.
- qa
--prerender=falsefor that project succeeds. - SSR title and theme match the tenant. Login stays branded.
/creatorsvs cover behaves like 18 for that tenant.
Leave dirty on the machine
src/environments/environment.tsif you pointed it at QA.- Prefetch marketing files after
prerender-all-qa. - A cloned tenant in
angular.json. Pull it out after the smoke orgetDistFolderwill pick the wrong dist.
The red Vite overlay is Chrome
- Look
[plugin:vite:json] Failed to parse JSON fileon/.well-known/appspecific/com.chrome.devtools.json.- Cause
- Chrome probes that URL on localhost so DevTools can map the folder. Angular 19's Vite 6 treats any
.jsonpath as a module, getsindex.html, and the overlay screams. Expressserve:ssrnever does this. - Call
- Dismiss it. Do not ship a dummy JSON into
dist/to shut it up. Later CLI versions added a middleware. We are on 19.2.27, which does not have it.
Do not file as a 19 bug
- Create Plan disabled when 1 Month is selected and Total Price is empty. That is
checkFormDisablefrom before. ng lintrunning out of memory.- PrimeNG still saga-blue. That stay is the upgrade decision.
- Prefetch-generated marketing files changing after
prerender-all-qa. Restore them. Do not merge them. - HMR on
ng serveby default. If styles ghost,npm run start:no-hmr.
Scripts you should see
package.jsonstart ng serve (style HMR on)start:no-hmr ng serve --no-hmrnode:start 10GB heap + serveserve:ssr Express from distgone start:hmr, dev:hmr, node:start:hmr, dev:ssr
If SSR hosts work and a logged-in reel can open and close those four sheets, 19 is in. The white frame on the sheet is homework, not a rollback.
Branch feature/release-0.0.23/16-17-18-19. Companion: Angular 15 to 19.