How to build and deploy ASP.NET Core with Angular SSR?

Programming, error messages and sample code > ASP.NET
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.
  1. Open Visual Studio 2026 and click "Create a new project"
  1. Search Angular and choose "Angular and ASP.NET Core"
  1. Your solution explorer will look like this
  1. 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
 
  1. 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.
  1. The next step is to publish it to our server, but before that, you need to confirm these things:
    1. In Solution Explorer, right-click the AngularApp1.Server project and select Add > Project Reference. Make sure the AngularApp1.client project is selected.
    2. Make sure the project reference includes a <ReferenceOutputAssembly> element with the value set to false in the .csproj file of AngularApp1.Server project.
    3. Add app.UseStaticFiles(); into the Program.cs
  2. 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?"