Skip to content

Prerendered home page overwrites app-shell, causing flash of home page on non-prerendered routes #28580

@aeslinger0

Description

@aeslinger0

Command

build

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

This is a follow-up to #28344

I have an Angular 18 site in which I implemented app-shell. In my angular.json I have "prerender": true and "ssr": false and when I run ng build, I can see the shell contents in the main index.html as expected.

However, if I add a route for the homepage such as { path: '', loadComponent: () => import('src/app/dashboard/dashboard.component').then(x => x.DashboardComponent) }, then I see the prerendered content of dashboard instead of shell in the index.html. I believe this is why the dashboard content flashes for a moment when navigating to deep links for non-prerendered routes.

The workaround is to have your homepage route be something like /home instead of / and then include { path: '', pathMatch: 'full', redirectTo: 'home' } in your routes, however, this redirect costs me ~300ms according to Chrome Lighthouse and I would like the canonical url of my root page to actually be my root page.

How can I prerender the site including the homepage which has a route of /, but still have the shell display while loading deep links to non-prerendered routes?

Minimal Reproduction

  • Create a new app by following the app-shell pattern.
  • Modify angular.json to have "prerender": true and "ssr": false.
  • Add one route without parameters (which will prerender) and one route with parameters (which will not prerender)
  • Run ng build.
  • Notice app-shell is in the index.html.
  • Run http-server on the dist folder.
  • Notice that reloading on the prerendered route flashes the prerendered content of that route as expected.
  • Notice that reloading on the non-prerendered route flashes the app-shell as expected.
  • Add a component for the home page such as ng g c dashboard.
  • Add a route for the home page using { path: '', loadComponent: () => import('src/app/dashboard/dashboard.component').then(x => x.DashboardComponent) }.
  • Run ng build again.
  • Notice app-shell has been replaced by dashboard content.
  • Run http-server on the dist folder.
  • Notice that reloading on the non-prerendered route now flashes the dashboard content instead of the app-shell.

Exception or Error

No response

Your Environment

Angular CLI: 18.2.3
Node: 22.3.0
Package Manager: yarn 1.22.17
OS: win32 x64

Angular: 18.0.4
... animations, cdk, cdk-experimental, common, compiler, core
... elements, forms, material, platform-browser
... platform-browser-dynamic, platform-server, router

Package Version

@angular-devkit/architect 0.1802.1
@angular-devkit/build-angular 18.2.1
@angular-devkit/core 18.2.3
@angular-devkit/schematics 18.2.3
@angular/cli 18.2.3
@angular/compiler-cli 18.2.3
@angular/ssr 18.2.0
@schematics/angular 18.2.3
rxjs 7.8.1
typescript 5.4.5
zone.js 0.14.10

Anything else relevant?

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions