Skip to content

Problems and errors with enforcing SSR using ServerRoutes #31666

@vz-tl

Description

@vz-tl

Which @angular/* package(s) are the source of the bug?

platform-server

Is this a regression?

No

Description

I'm trying to get our SSR application to work with application-builder and the new AngularNodeAppEngine.

In our use case we only want to do SSR, no SSG. Also, we do not want to make use of any ServerRoutes features, as anyway all routes should be SSR, and redirects or status codes will already be handled by the application logic.

In order to enforce all routes being SSR, I had to explicitly configure the app server config with:

provideServerRendering(
  withRoutes([
    {
      path: '**',
      renderMode: RenderMode.Server
    }
  ])
)

Issue 1:

There's no global switch to simply turn off SSG and I'm forced to add withRoutes with a catch-all route, even though I do not want to use any of the related features.

Hence it would be very useful to introduce a withNoRoutes() option, which also should disable the initial route evaluation/extraction while running a dev server - which is simply wasted computation time in our case.

As I do not want SSG, I already configured "outputMode": "server" in angular.json. I'm wondering why this setting isn't enough to turn off SSG completely, so that all pages will be SSR by default, not requiring withRoutes() configured.

Issue 2:

Our routing setup includes a lot of lazy-load child routes. If one of the child routes has a matcher applied, then I get the below error:

Error: Error(s) occurred while extracting routes:
The route 'test/**' has a defined matcher but does not match any route in the server routing configuration. Please ensure this route is added to the server routing configuration.

My (simplified) routing setup is as follows:

App routes:

{
  path: 'test',
  loadChildren: () => import('@my-app/test/feature').then(m => m.testFeatureRoutes)
},

Test feature routes:

  {
    path: '',
    pathMatch: 'full',
    component: TestComponent
  },
  {
    matcher: () => null, <-- this guy here causes the error
    component: TestComponent
  },

Am I really forced now to add for all such routes a dedicated entry like test/** to ServerRoutes? In cases with very dynamic routing it seems to me also impossible or at least cumbersome to add all required sub-route catch-alls. Also, it's actually quite bad DX if one is bothered with having to solve errors for features he/she doesn't want to use anyway.

So, to me the both issues I described are tightly coupled:
If I would be able to turn off server routing completely, I wouldn't have to solve the problems with the catch-alls when using matchers.

Looking forward to some answers explaining to me what can be done to get around the above mentioned obstacles.

Please provide a link to a minimal reproduction of the bug

Please provide the exception or error you saw

See above

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 20.3.5
Node: 22.18.0
Package Manager: npm 10.9.3
OS: linux x64
    

Angular: 20.3.4
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... platform-server, router

Package                         Version
---------------------------------------
@angular-devkit/architect       0.2003.5
@angular-devkit/build-angular   20.3.5
@angular-devkit/core            20.3.5
@angular-devkit/schematics      20.3.5
@angular/cdk                    20.2.8
@angular/cli                    20.3.5
@angular/google-maps            20.2.8
@angular/ssr                    20.3.5
@angular/youtube-player         20.2.8
@schematics/angular             20.3.5
ng-packagr                      20.3.0
rxjs                            7.8.2
typescript                      5.9.3
zone.js                         0.15.1

Anything else?

No response

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions