Why SSR?
Angular ships all applications as client-side rendered (CSR) by default. While this approach delivers an initial payload that's lightweight, it introduces trade-offs including slower load times, degraded performance metrics, and higher resource demands since the user's device performs most of the computations. As a result, many applications achieve significant performance improvements by integrating server-side rendering (SSR) into a hybrid rendering strategy.
The environment of this demo:
Operating system: Windows
IDE: Visual Studio 2026
Angular CLI: 19.2.19
Node: 18.19.1
Package Manager: npm 10.2.4
windows-build-tools
Now, let's do it.
-
Open Visual Studio 2026 and click "Create a new project"
.png)
-
Search Angular and choose "Angular and ASP.NET Core"
.png)
-
Your solution explorer will look like this

-
Go to Angular application's root folder and enable SSR for Angular application
cd the\path\of\angular --Please use the real path in your local
ng add @angular/ssr
.png)
-
Start your project and "View page source"(shortcut is Ctrl + U) in the browser, find <app-root> node/tag, you will find it shows all the child elements, which is not like Angular SPA. Great, this means your SSR project works well.
.png)
-
The next step is to publish it to our server, but before that, you need to confirm these things:
-
In Solution Explorer, right-click the AngularApp1.Server project and select Add > Project Reference. Make sure the AngularApp1.client project is selected.
-
Make sure the project reference includes a <ReferenceOutputAssembly> element with the value set to false in the .csproj file of AngularApp1.Server project.
-
Add app.UseStaticFiles(); into the Program.cs
-
Right-click AngularApp1.Server project > Publish, for more details, you can refer to
here
Troubleshooting
Case 1: Not all elements can be rendered on the server, such as running timers, making API calls, or performing other dynamic operations that should only occur when a real user interacts with the page. You may encounter this error when publishing your application.
An error occurred while prerendering route '/'. Unable to handle request: '/xxx'
Solution:
Step 1: Import the Necessary Tools
import { Component, OnDestroy, OnInit, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
Step 2: Inject the Platform Identifier
constructor(@Inject(PLATFORM_ID) private platformId: Object, private http: HttpClient) { }
Step 3: Check Before Starting Interactive Features
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
this.getForecasts(); //use your own function here
}
}
Now, you can rebuild and republish application to server.
PS.
Available in Both Node.js and the Browser:
setInterval(), setTimeout(), console.log()
Basic JavaScript features
Most npm packages that don’t rely on the DOM
Only Available in Browser:
window, document, navigator
localStorage, sessionStorage, cookies
DOM APIs (querySelector, addEventListener, etc.)
Browser-specific APIs (Geolocation, Camera, etc.)
The Key Question: Not "Does this exist in Node.js?" but "Should this run during prerendering?"