@@ -45,7 +45,7 @@ const VALID_REDIRECT_RESPONSE_CODES = new Set([301, 302, 303, 307, 308]);
4545 */
4646type ServerConfigRouteTreeAdditionalMetadata = Partial < ServerRoute > & {
4747 /** Indicates if the route has been matched with the Angular router routes. */
48- matched ?: boolean ;
48+ presentInClientRouter ?: boolean ;
4949} ;
5050
5151/**
@@ -134,15 +134,15 @@ async function* traverseRoutesConfig(options: {
134134 continue ;
135135 }
136136
137- matchedMetaData . matched = true ;
137+ matchedMetaData . presentInClientRouter = true ;
138138 }
139139
140140 const metadata : ServerConfigRouteTreeNodeMetadata = {
141141 ...matchedMetaData ,
142142 route : currentRoutePath ,
143143 } ;
144144
145- delete metadata . matched ;
145+ delete metadata . presentInClientRouter ;
146146
147147 // Handle redirects
148148 if ( typeof redirectTo === 'string' ) {
@@ -246,8 +246,8 @@ async function* handleSSGRoute(
246246 if ( ! getPrerenderParams ) {
247247 yield {
248248 error :
249- `The '${ stripLeadingSlash ( currentRoutePath ) } ' route uses prerendering and includes parameters, but 'getPrerenderParams' is missing. ` +
250- `Please define 'getPrerenderParams' function for this route in your server routing configuration ` +
249+ `The '${ stripLeadingSlash ( currentRoutePath ) } ' route uses prerendering and includes parameters, but 'getPrerenderParams' ` +
250+ `is missing. Please define 'getPrerenderParams' function for this route in your server routing configuration ` +
251251 `or specify a different 'renderMode'.` ,
252252 } ;
253253
@@ -442,24 +442,38 @@ export async function getRoutesFromAngularRouterConfig(
442442 includePrerenderFallbackRoutes,
443443 } ) ;
444444
445+ let seenAppShellRoute : string | undefined ;
445446 for await ( const result of traverseRoutes ) {
446447 if ( 'error' in result ) {
447448 errors . push ( result . error ) ;
448449 } else {
450+ if ( result . renderMode === RenderMode . AppShell ) {
451+ if ( seenAppShellRoute !== undefined ) {
452+ errors . push (
453+ `Error: Both '${ seenAppShellRoute } ' and '${ stripLeadingSlash ( result . route ) } ' routes have ` +
454+ `their 'renderMode' set to 'AppShell'. AppShell renderMode should only be assigned to one route. ` +
455+ `Please review your route configurations to ensure that only one route is set to 'RenderMode.AppShell'.` ,
456+ ) ;
457+ }
458+
459+ seenAppShellRoute = stripLeadingSlash ( result . route ) ;
460+ }
461+
449462 routesResults . push ( result ) ;
450463 }
451464 }
452465
453466 if ( serverConfigRouteTree ) {
454- for ( const { route, matched } of serverConfigRouteTree . traverse ( ) ) {
455- if ( matched || route === '**' ) {
467+ for ( const { route, presentInClientRouter } of serverConfigRouteTree . traverse ( ) ) {
468+ if ( presentInClientRouter || route === '**' ) {
456469 // Skip if matched or it's the catch-all route.
457470 continue ;
458471 }
459472
460473 errors . push (
461- `The server route '${ route } ' does not match any routes defined in the Angular routing configuration. ` +
462- 'Please verify and if unneeded remove this route from the server configuration.' ,
474+ `The '${ route } ' server route does not match any routes defined in the Angular ` +
475+ `routing configuration (typically provided as a part of the 'provideRouter' call). ` +
476+ 'Please make sure that the mentioned server route is present in the Angular routing configuration.' ,
463477 ) ;
464478 }
465479 }
0 commit comments