diff --git a/packages/angular/ssr/src/routes/ng-routes.ts b/packages/angular/ssr/src/routes/ng-routes.ts index 04f67c96d9d5..ac83aae8cd4f 100644 --- a/packages/angular/ssr/src/routes/ng-routes.ts +++ b/packages/angular/ssr/src/routes/ng-routes.ts @@ -547,7 +547,7 @@ function resolveRedirectTo(routePath: string, redirectTo: string): string { } // Resolve relative redirectTo based on the current route path. - const segments = routePath.replace(URL_PARAMETER_REGEXP, '*').split('/'); + const segments = routePath.replace(URL_PARAMETER_GLOBAL_REGEXP, '*').split('/'); segments.pop(); // Remove the last segment to make it relative. return joinUrlParts(...segments, redirectTo); diff --git a/packages/angular/ssr/test/routes/ng-routes_spec.ts b/packages/angular/ssr/test/routes/ng-routes_spec.ts index 1532eb337faa..e214c31eab71 100644 --- a/packages/angular/ssr/test/routes/ng-routes_spec.ts +++ b/packages/angular/ssr/test/routes/ng-routes_spec.ts @@ -502,6 +502,35 @@ describe('extractRoutesAndCreateRouteTree', () => { ]); }); + it('should extract nested redirects with multiple path parameters', async () => { + setAngularAppTestingManifest( + [ + { + path: ':param1/:param2', + children: [ + { + path: '', + pathMatch: 'full', + redirectTo: 'thing', + }, + { + path: 'thing', + component: DummyComponent, + }, + ], + }, + ], + [{ path: '**', renderMode: RenderMode.Server }], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { route: '/*/*', renderMode: RenderMode.Server, redirectTo: '/*/*/thing' }, + { route: '/*/*/thing', renderMode: RenderMode.Server }, + ]); + }); + it('should not resolve parameterized routes for SSG when `invokeGetPrerenderParams` is false', async () => { setAngularAppTestingManifest( [