🧠 Angular SSR in Version 20: Understanding Server-Side Rendering, Client-Side Rendering & Pre-Rendering
Welcome to this deep dive into Angular’s rendering strategies, including Server-Side Rendering (SSR), Client-Side Rendering (CSR), and Pre-Rendering, especially with the latest Angular v20 features like incremental hydration.
Whether you're building a public-facing marketing site, an internal dashboard, or a dynamic product listing page, understanding how Angular renders your application can significantly impact performance, SEO, and user experience.
In this comprehensive guide, we'll explore:
- What Server-Side Rendering (SSR) is
- The differences between SSR, CSR, and Pre-Rendering
- How to enable SSR in Angular v20
- A practical comparison of each mode using logging and source inspection
- When to choose which rendering strategy
- Insights into hydration, defer blocks, and upcoming topics like Zoneless mode
Let’s get started!
Latest from angular
Bookmark This Article
Your browser doesn't support automatic bookmarking. You can:
- Press Ctrl+D (or Command+D on Mac) to bookmark this page
- Or drag this link to your bookmarks bar:
Clicking this bookmarklet when on any page of our site will bookmark the current page.
🧠 What Is Server-Side Rendering (SSR)?
Server-Side Rendering (SSR) means that the HTML content is generated on the server, on demand, for each incoming request.
When a user navigates to a route, the server processes the request, runs the Angular application on the server, and returns fully rendered HTML to the browser.
This approach ensures: - Users see meaningful content immediately - No flicker or loader before the app becomes interactive - Better SEO, as crawlers receive pre-rendered content - Predictable data fetching workflows (e.g., querying a database directly from the server)
💡 The keyword here is “on demand” – meaning every request triggers a fresh render on the server.
✅ Benefits of SSR:
- Faster First Paint: Content appears sooner.
- Improved SEO: Search engines index rendered content easily.
- Predictable Data Fetching: APIs and databases can be queried during rendering.
- No Blank Screen: Avoids showing loaders until JavaScript executes.
🚀 SSR vs CSR vs Pre-Rendering: A Comparative Breakdown
| Feature | Client-Side Rendering (CSR) | Server-Side Rendering (SSR) | Pre-Rendering | |--------|----------------------------------|----------------------------------|--------------------| | Initial Load | Minimal HTML + JS bundle | Fully rendered HTML | Static HTML (built once) | | SEO-Friendly | ❌ Not ideal | ✅ Excellent | ✅ Good | | Performance | Fast after first load | Slower initial load due to server processing | Very fast (static HTML) | | Dynamic Content | Requires client-side fetch | Can fetch during server render | Only static content |
🔁 Client-Side Rendering (CSR)
In CSR, the server sends a minimal HTML shell along with the Angular JavaScript bundle.
Once the JavaScript loads, Angular bootstraps itself and dynamically generates the UI.
This works well for SPAs where subsequent navigation is fast and SEO isn’t critical.
Best Use Cases: - Dashboards - Internal tools - Admin panels
🖥️ Server-Side Rendering (SSR)
With SSR, the server renders the full HTML of the page and sends it to the browser.
Every request triggers a new render on the server. This is ideal for dynamic content such as blog posts, product pages, or any data pulled from a database.
Best Use Cases: - Public-facing websites - Pages needing SEO - Content updated frequently
🧊 Pre-Rendering (Static Generation)
Pre-rendering generates HTML at build time instead of on each request. It's great for static content like landing pages, FAQs, or documentation.
You build once, deploy anywhere – no server needed afterward.
Best Use Cases: - Static pages (terms, privacy policy) - Marketing sites - Documentation
⚙️ Enabling SSR in Angular v20
Angular v20 brings streamlined SSR setup via the CLI, better integration with Express.js, and improved developer tooling around hybrid rendering strategies.
To create a new Angular project with SSR enabled, follow these steps:
1. Install Angular CLI (v20)
npm install -g @angular/cli@latest
2. Create a New Project with SSR
ng new ngv20-demo-app --ssr
Choose CSS
for styling and say No to Zoneless mode for now.
This command sets up an Angular app with Express.js integration for SSR out of the box.
🔍 Angular v20 Note: The CLI now auto-generates more robust SSR boilerplate, reducing the need for manual configuration and improving compatibility with newer Node.js versions.
3. Build and Serve the App
ng build
npm run serve:ssr
Your app will now be available at http://localhost:4000
.
📂 Project Structure Overview (Angular v20)
Inside the generated project, you’ll notice:
src/main.server.ts
: Entry point for the server-side application.src/server.ts
: Sets up the Express server.src/app.routes.ts
: Defines the rendering strategy (server
,client
, orprerender
).dist/
folder contains two subfolders:browser/
: Client-side assetsserver/
: Server-side bundle
🔍 Angular v20 Note: SSR now supports custom document transformers, allowing fine-grained manipulation of the final HTML output before sending it to the client.
🧪 Practical Comparison: Testing Each Mode
Let’s walk through how to test the differences using logging and source inspection.
Step 1: Add Logging in AppComponent
Open app.component.ts
and add:
```ts
import { Component, OnInit } from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit { ngOnInit() { console.log('App initialized'); } } ```
Step 2: Change Render Mode in app.routes.ts
Update the renderMode
in your routes:
ts
{
path: '',
component: AppComponent,
data: { renderMode: 'server' } // Try 'client' or 'prerender' too
}
Step 3: Run the App in Dev Mode
Use:
bash
ng serve
Navigate to http://localhost:4200
and inspect the logs in both the terminal and the browser console.
🔍 View Page Source to See Differences
Right-click on the page and click "View Page Source".
In CSR Mode:
- You’ll see only the basic HTML shell (
<app-root>
placeholder) - JavaScript handles rendering after download
In SSR Mode:
- You’ll see the full rendered HTML inside
<app-root>
- Every reload triggers a new render on the server
In Pre-Render Mode:
- You’ll also see the full HTML
- But the log only shows once during the build process
🧪 Observing Logs Across Modes
| Mode | Log Appears On | Notes |
|------|----------------|-------|
| server
| Server terminal on every request | Real-time rendering |
| client
| Browser console only | SPA behavior |
| prerender
| During build only | Static HTML |
🧠 Angular v20 Insight: With the introduction of Incremental Hydration, developers can now selectively hydrate parts of the app as they become visible, improving performance while still leveraging SSR benefits.
📈 Choosing the Right Strategy
| Scenario | Recommended Mode | |---------|------------------| | Public-facing, SEO-critical pages | SSR | | Internal dashboards or tools | CSR | | Static content (FAQs, docs, terms) | Pre-render | | Resource-constrained servers | CSR or Pre-render | | Frequent dynamic updates | SSR |
🛠️ Behind the Scenes: How Angular Handles SSR
When you enable SSR, Angular uses Express.js under the hood.
The main file responsible for this is server.ts
, which imports express
and @angular/ssr/node
.
It uses renderModuleFactory
to generate the HTML on the server, then sends it to the browser.
This setup allows developers to have full control over server-side logic, including custom middleware and API integrations.
🧱 Angular v20 Note: SSR now supports custom document transformers, allowing fine-grained manipulation of the final HTML output before sending it to the client.
🧱 Hydration: Making SSR Interactive
One of the most exciting features coming in Angular v20 is Incremental Hydration.
Hydration is the process of turning server-rendered HTML into a fully interactive Angular application on the client side.
In future articles, we’ll explore: - Incremental Hydration and how it improves performance - Defer Blocks to lazy-load parts of your app - Zoneless mode and its impact on change detection and performance
🔁 Angular v20 Note: Incremental Hydration lets you hydrate only essential parts of the app first, deferring non-critical components. This leads to faster interactivity without sacrificing SSR quality.
📘 Upcoming Book: Mastering Angular Signals
If you want to take your Angular knowledge further, stay tuned for my upcoming book “Mastering Angular Signals”, which dives into advanced techniques for building performant, scalable apps with Angular’s modern architecture.
🎯 Summary: Key Takeaways
- SSR renders HTML on the server for every request – best for SEO and dynamic content.
- CSR lets Angular render everything in the browser – best for SPAs and internal tools.
- Pre-rendering generates HTML at build time – best for static pages.
- Use logging and page source inspection to verify which mode you're in.
- Choose the right strategy based on your use case, resources, and performance goals.
🧩 Next Steps
In the next video/article in this series, we’ll explore Defer Blocks, a powerful new feature in Angular that allows you to lazy-load parts of your app without blocking the initial render.
We’ll look at how defer blocks work with SSR and how they can improve performance and reduce initial bundle size.
💬 Final Thoughts
Understanding the different rendering modes in Angular gives you the flexibility to optimize for speed, SEO, and scalability.
With Angular v20 making SSR easier than ever, there's no reason not to leverage it for applications that need high performance and better search engine visibility.
Stay tuned for more in this multi-part series!