Use Server Routes with Angular SSR to granularly specify render modes
When building modern Angular applications, especially public-facing ones, Server-Side Rendering (SSR) is a powerful tool for enhancing SEO and improving initial page load performance. But what if you need different rendering strategies for different routes? Angular's Server Routes feature provides an elegant solution for granular control over render modes.
What are Server Routes?
Server Routes allow you to define an array of ServerRoute objects, each specifying a path and a renderMode for that specific route. This means you can mix and match rendering strategies within a single Angular application – choosing between pre-rendering, server-side rendering, or even client-side rendering on a per-route basis.
Why is this useful?
This granular control offers several key benefits:
- Optimized SEO: Prerender critical, public-facing content (like product pages or blog posts) at build time to ensure search engines can easily index them.
- Improved Performance: Deliver fully rendered HTML for essential pages, providing a faster initial load experience for users.
- Flexibility: Use client-side rendering for highly dynamic or user-specific authenticated routes (like a user's wishlist or profile) where SEO isn't a primary concern, or server-side rendering for routes that need fresh data on each request.
- Dynamic Pre-rendering: Generate static pages for dynamic content (like product categories) by fetching data during the build process, saving on server computation at runtime.
How to use it
Let's look at a practical example where we pre-render product category pages and use client-side rendering for a wishlist.
import { RenderMode, ServerRoute } from '@angular/ssr';
import { CategoriesApi } from './services/categories-api';
import { inject } from '@angular/core';
export const serverRoutes: ServerRoute[] = [
{
path: 'products/:categoryName',
renderMode: RenderMode.Prerender,
async getPrerenderParams() {
// Dynamically fetch categories during the build process
const catService = inject(CategoriesApi);
const names = await catService.getCategories();
// Return parameters for each category to be pre-rendered
return names.map((name) => ({ categoryName: name }));
},
},
{
path: 'wishlist',
renderMode: RenderMode.Client, // Client-side rendering for this route
},
// ... more routes with different render modes
];
In this snippet:
products/:categoryName: We've setrenderMode: RenderMode.Prerender. ThegetPrerenderParamsfunction is executed at build time. It usesinjectto get an instance ofCategoriesApiand fetches all category names. For eachcategoryName, a separate static HTML file will be generated (e.g.,/products/electronics,/products/books). Keep in mind that a very large number of categories could significantly increase your build time.wishlist: This route usesrenderMode: RenderMode.Client. This means it will primarily be rendered on the browser, suitable for pages that are highly interactive, user-specific, or don't require immediate SEO benefits. You could also opt forRenderMode.Serverhere if you wanted server-side rendering without pre-generation.
By exporting this serverRoutes array, your Angular SSR application can intelligently apply the right rendering strategy for each part of your site. It's a simple yet powerful way to build high-performance, SEO-friendly Angular applications.
Full code (with firebase, stripe backend) on my shop: https://zoaibkhan.com/shop/angular-ecommerce?utm_source=server-routes-snippet
