I’m migrating an Angular 18 project to Angular 19. Previously, I used a routes.txt file for server prerendering (SSG), and it worked fine. Now, with Angular 19, I switched to the RenderMode (Hybrid Rendering) configuration in app.routes.server.ts, but I’m facing the following problem:
[ERROR] The 'archives/*' server route does not match any routes defined in the Angular routing configuration...
I get this message for several routes that used to work normally in SSR/SSG. In my app.routes.ts, there is literally no ‘archives/*’ path. Instead, I have something like:
// app.routes.ts
import { Routes, UrlSegment } from '@angular/router';
// 1) The custom matcher:
export function friendlyUrlMatcher_Or_SumarioIdUrlMatcher(url: UrlSegment[]) {
// The idea is to match either a user-friendly slug
// (e.g. "my-article-slug") or a numeric ID (e.g. "123")
const regex = /^[a-zA-Z]{3,}(-[a-zA-Z]{3,})+$/; // e.g.: "my-friendly-url"
const numericRegex = /^[1-9][0-9]{0,4}$/; // e.g.: "123"
if (url.length >= 1 && (regex.test(url[url.length - 1].path) || numericRegex.test(url[url.length - 1].path))) {
return {
consumed: url,
posParams: {
sumarioId: url[0], // or url[url.length - 1]
},
};
} else {
return null;
}
}
// 2) The archives route with sub-routes:
export const routes: Routes = [
// ... other routes ...
{
path: 'archives',
children: [
{
path: 'page/:page',
// loadComponent, canActivate, etc.
},
{
path: 'vol/:vol',
// loadComponent, canActivate, etc.
},
{
path: ':sumarioId/:pathParam',
// loadComponent, etc.
},
{
// This uses the custom matcher:
matcher: friendlyUrlMatcher_Or_SumarioIdUrlMatcher,
// loadComponent, canActivate, etc.
},
{
path: '',
pathMatch: 'full',
redirectTo: 'page/1',
},
],
},
// ... other routes ...
];
But in app.routes.server.ts, I tried something like:
// app.routes.server.ts
import { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [
{
path: 'archives/:id',
renderMode: RenderMode.Prerender,
async getPrerenderParams() {
// ...
},
},
{
path: 'archives/**',
renderMode: RenderMode.Server,
},
// other routes...
];
Then I get the error that ‘archives/*’ or ‘archives/**’ doesn’t match anything defined in the Angular routing. Under Angular 18, I just listed the routes in routes.txt and did the prerender build without issues. Now, as far as I understand, Angular 19 requires a literal match on both the client and server side. I don’t really want to remove the matcher or create an “alias” route for each case, since that would require a larger refactor.
Question: Has anyone faced a similar situation and found a solution without replacing the matcher with a literal path or creating a route alias? Is there any way to keep the matcher working and still do SSR/SSG without that “route not found” error in app.routes.server.ts?