For a large Angular app with marketing pages, a product catalogue and a signed-in account area, how would you assign @angular/ssr render modes per route?
answer
- what drives each route's choice
- request dependence and indexing
- change rate and URL count
- the default ** entry is a policy
basics
~20 sPrerender pages that are identical for everyone and must rank, render per request (Server) pages that depend on the request or change often, and use Client for per-user areas nobody indexes, choosing the ** default deliberately.
solid answer
~40 sI would decide each route from a few drivers: does its HTML depend on the request, does anyone need HTML before scripts run, how often does it change, and how many URLs does it have. Marketing pages are the same for everyone and must be indexed, so `RenderMode.Prerender`. The catalogue prerenders the popular, stable pages and renders the rest with `RenderMode.Server`; search results depend on the query, so `Server`. The account area is per-user and never indexed, so `RenderMode.Client` avoids forwarding sessions and caching risks, unless first paint there justifies `Server` with private cache headers. I would pick the `**` default deliberately, let route extraction fail builds on uncovered routes, and revisit modes as traffic and content change.
code
ts · 17 linesimport { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [
// indexed, same for everyone
{ path: '', renderMode: RenderMode.Prerender },
{ path: 'pricing', renderMode: RenderMode.Prerender },
// depends on the query string
{ path: 'search', renderMode: RenderMode.Server },
// per-user, never indexed
{
path: 'account/**',
renderMode: RenderMode.Client,
headers: { 'Cache-Control': 'no-store' },
},
// unknown URLs reach code that can set a 404
{ path: '**', renderMode: RenderMode.Server },
];go deeper
Recall which kind of page fits Prerender, Server and Client, using a marketing page, a search page and an account page as examples.
Explain how request dependence and indexing decide a route's mode, and what code constraints Prerender and Server impose that Client does not.
Anticipate the failures of a wrong assignment, such as request-dependent pages prerendered once or a Prerender catch-all that cannot return 404.
Turn the assignment into a policy: a deliberate ** default, recorded reasons per route, build-enforced coverage, and metrics that tell you when a route should change mode.
## The shape of the problem A large Angular application rarely has one right rendering mode. With `@angular/ssr`, the `ServerRoute[]` list passed to `withRoutes()` lets each path choose `RenderMode.Prerender`, `RenderMode.Server` or `RenderMode.Client`, so the real work is deciding **which property of each page drives the choice** and making that decision reviewable. For a site with marketing pages, a product catalogue and a signed-in account area, a defensible first plan looks like this: | Area | Mode | Main reason | What it costs | | --- | --- | --- | --- | | Home, pricing, docs | `Prerender` | Same HTML for everyone, must rank in search | Build time, a redeploy to change copy | | Catalogue listing and product pages | `Prerender` for the stable set, `Server` for the rest | Search traffic plus data that changes | Server renders for the non-prerendered part | | Search results with query strings | `Server` | Output depends on the request | A render per request | | Account area | `Client` | Per-user, never indexed | Slower first paint for signed-in users | | Catch-all `**` | `Server` with a real 404 path | Unknown URLs need correct status codes | Small | ## Questions that decide each route 1. **Does the HTML depend on the request?** If it reads cookies, headers or the query through `inject(REQUEST)`, it cannot be `Prerender`: the build has no request and renders the fallback branch once for everyone. 2. **Does anyone need the HTML before scripts run?** Search engines and link previews do; a signed-in dashboard usually does not. If nobody does, `Client` removes server work and a class of server-only bugs. 3. **How often does it change, and who changes it?** Prerendered pages change only on a build. Content that editors change hourly either needs frequent builds or `Server`. 4. **How many URLs?** Prerendering tens of thousands of pages slows every build and deployment; prerender the popular subset and let the rest render on request. Enumerating parameters and choosing fallbacks is its own mechanism. ## Why the account area is often Client Server-rendering a signed-in area means forwarding the session to the server render, reading it from `REQUEST`, calling user-specific APIs from the server, and making sure no shared cache ever stores the result. With `RenderMode.Client` the server returns the shell, the browser authenticates as it always did, and browser-only libraries work unchanged. The cost is a blank-then-rendered first view. Teams that need a fast first paint there choose `Server` instead, and then own the session forwarding and caching headers explicitly (a route's `headers` field can send, for example, `Cache-Control: private, no-store`). ## Making it a policy, not a list - **Pick the default deliberately.** The generated list is one `**` entry set to `Prerender`; for an app with many dynamic pages, a `Server` or `Client` default is often safer, with `Prerender` opted into per path. - **Let the build enforce coverage.** Route extraction fails when an Angular route has no matching server route or a server route matches no Angular route, which turns a forgotten route into a build error rather than a silent default. - **Write server-safe code everywhere that is not `Client`.** `Prerender` and `Server` both execute components outside a browser. - **Record the reason per route.** A short comment beside each entry (for example `// indexed, same for everyone`) lets reviewers challenge a change. - **Measure after the change.** Watch build duration, server CPU per request and first-paint metrics per area; a mode is a hypothesis about those numbers. ## Where teams go wrong - Prerendering pages that quietly read the request, so every visitor gets the build machine's version. - Server-rendering everything "for SEO", including pages no crawler can reach, and paying for renders nobody benefits from. - Leaving the catch-all as `Prerender` without checking what unknown URLs actually return, since no request-time code runs for them. - Treating the choice as permanent: a route's mode is one line, and it should move when traffic or content changes. There is no single correct table. A strong answer names the drivers (request dependence, indexing, change rate, URL count, code constraints), assigns modes from them, and says how the team will notice when an assignment has become wrong.
- When would you server-render the account area instead?When a fast first view for signed-in users matters enough to pay for it. Then the server render must receive the session, read it through `REQUEST`, call user APIs from the server, and send headers such as `Cache-Control: private, no-store` so no shared cache keeps one user's page.
- What signals would make you change a route's mode later?Build duration growing with prerendered URLs, server CPU spent on pages that never vary, editors waiting for deploys to publish copy, or search traffic landing on a Client route. Each points at a route whose mode no longer matches its drivers.
saying these in an interview costs you the question
- Server-render every route because SSR is always better for SEO
- Prerender the account area to make it load faster
- One render mode should be picked for the whole application
- The generated ** Prerender default is right for any app
- Prerendered pages can safely read cookies through inject(REQUEST)