angular-cli: App Shell not generated when wildcard route (not found page) is present in app
Versions
Angular CLI: 1.6.1
Node: 8.9.0
OS: darwin x64
Angular: 5.1.1
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
@angular/cli: 1.6.1
@angular-devkit/build-optimizer: 0.0.36
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.42
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.1
@schematics/angular: 0.1.11
@schematics/schematics: 0.0.11
typescript: 2.4.2
webpack: 3.10.0
Repro steps
- Follow the steps to add an app shell to angular universal app as described here
- Create a ‘not-found’ component with the following angular-cli command:
ng generate component not-found --skip-import
- Import and add the NotFoundComponent to
app-routing.module.ts
:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { NotFoundComponent } from './not-found/not-found.component';
const routes: Routes = [
{ path: '**', component: NotFoundComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
- Import and add NotFoundComponent to declarations array in
app.module.ts
- Run
ng build --prod
- Inspect
dist/index.html
Observed behavior
dist/index.html
includes the <app-not-found>
tag for the NotFoundComponent. See the snippet below:
<router-outlet _ngcontent-c0=""></router-outlet><app-not-found _nghost-c1=""><p _ngcontent-c1="">
not-found works!
</p>
</app-not-found>
Desired behavior
dist/index.html
should include the <app-app-shell>
tag for the AppShellComponent. See the snippet below:
<router-outlet _ngcontent-c0=""></router-outlet><app-app-shell _nghost-c1=""><p _ngcontent-c1="">
app-shell works!
</p>
</app-app-shell>
Mention any other details that might be useful (optional)
Based on the documentation I could find about the App Shell feature introduced in Angular 5.1 (see here & here), I could not find anything detailing how the app shell should work when a wildcard route (aka ‘not found’ page) is present in an app’s routing config.
How should an app with a wildcard route be configured to support an app-shell and its accompanying route?
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 17
- Comments: 19 (3 by maintainers)
Sorry for what I posted earlier, I tested incorrectly and thought it was working. This time I investigated further and found a way to override the routes when rendering the app shell. Use the following workaround in your
app.server.module.ts
:This removes all routes that are imported by your regular
AppModule
, and replaces it with the app shell route, so the wildcard route is not blocking it from loading.@literalpie to your point, I think you are correct in that the
ng serve --prod
command can not be used to properly test app-shell in the browser. I just tried doing so and the app-shell is nowhere to be found.You have to generate a build with the
ng build --prod
command, and use a static server like http-server to serve it.After experimenting further, here is what ultimately worked for me:
app-routing.module.ts
app.server.module.ts
Note the addition of
{ path: '', redirectTo: '', pathMatch: 'full' }
in the routes. Although this is a simple solution and not something you would likely find in a real-world app, it is necessary for this example. Without it, Angular will not see the root url path (e.g.localhost:8080
) as a valid route. And in that case, thenot-found
component will be rendered at the root url path (afterapp-shell
first renders).Additionally,
this.router.resetConfig(routes);
must be called inAppServerModule
as @Manduro pointed out. Without it,app-shell
is not added to index.html afterng build --prod
is run andnot-found
is added instead.In order to test app-shell in this example, it is best to use network throttling in Chrome or Firefox (I tested with 2G and 3G).
All this is to say that I think this should still remain as an open bug because of the requirement to call
this.router.resetConfig(routes);
, which is not documented. Perhaps as a fix for this, Angular could do this internally so that devs to not manually have to. Thoughts?@Manduro I just tried your solution, but the issue still exists.
How shall we configure this for a standalone project? @Manduro thx ❤
app.config.server.ts
file:I also experienced that if I use the
APP_INITIALIZER
and try to redirect to an error page (based on our logic), App-shell navigates to that error page and embeds that page into our HTML instead of embedding the app-shell page itself! How this can be resolved?!app.config.ts
file:I did the
this.router.resetConfig(routes);
solution but instead ofapp-shell
now nothing is presented in<app-root>
. And CLI says that app-shell generated successfully.