In a file-based router, does a route with a parameterised path segment have to be rendered per request?
answer
- two senses of the same word
- path shape versus request dependence
- the path is identity, the query is intent
- one stored output per known value
basics
~20 sNo. A parameterised segment makes the URL shape dynamic, not the render. It can be prerendered once per known value, and becomes per-request only when the render reads request-bound input such as a cookie, header or query string.
solid answer
~50 sThe word "dynamic" is used for two different things and they are independent. A **dynamic segment** is a URL-shape fact: one route file serves many paths, such as a product slug. **Dynamic rendering** is a request fact: the output depends on what this particular request carries. A route with a parameterised path can be perfectly static — the framework produces one stored output per known value, and every visitor to that path gets the same bytes. What flips it is reading the cookie jar, a request header, the caller's address, or the query string. That last one is the practical trap: `/products/shoes` can be prerendered, but `/products/shoes?sort=price` normally cannot, because the query expresses per-visitor intent and enumerating every combination is impractical. How a framework decides which parameter values to prerender, and what a value it never saw receives, is a separate question.
go deeper
Keep the two meanings apart: a parameter in the path changes which URLs the route serves, while the request decides whether the output can be shared. They are set by different things.
Explain why a path value can be prerendered one file each while a query string normally cannot, and name the reads that actually move a parameterised route to per-request rendering.
Point out the dangerous direction — a per-visitor render forced into the prerendered set leaks one visitor's output to the next — and treat that as a correctness bug, not a tuning issue.
Use it when shaping URLs: promoting a high-traffic filter into a real path segment converts an unshareable render into thousands of cacheable documents, which is a design choice worth making deliberately.
## Two things called "dynamic" File-based routers borrowed the word "dynamic" for the URL, and rendering borrowed it for the request. They mean different things, and conflating them produces both of the classic mistakes: prerendering a route that genuinely cannot be shared, and rendering per request a route that could have been a file. | Sense | What varies | Decided by | |---|---|---| | Dynamic **segment** | Which path the route matches | The route's file or path pattern | | Dynamic **rendering** | Whether output depends on this request | What the render reads | A route can be any combination of the two: a fixed path rendered per request (a signed-in dashboard at one URL), and a parameterised path prerendered (thousands of product pages, each stored once). ## Why a parameterised path can still be static The path is part of the resource's identity. Two visitors asking for `/products/red-shoes` are asking for the same document, so one rendered output serves both. A prerendering framework treats the parameter as an input to the *set of outputs to produce*, not as request state: it produces one page per value and stores them, exactly as if you had written the files by hand. That is the entire reason large catalogues, documentation sites and blogs can be served as static files despite having one route file and tens of thousands of URLs. ## Where the query string sits The query string is attached to the URL but is normally treated as **request state**, for two reasons: - **It is unbounded.** A path can be enumerated from a data source; `?page`, `?sort`, `?filter` combinations multiply and cannot be listed. - **It expresses intent, not identity.** Two visitors at the same path with different queries usually want different views of the same resource. So a render that reads the query string typically flips the route to per-request. The common workaround is to keep the route prerendered and apply sorting, filtering and pagination in the browser, or to promote the important variants into real path segments so they can be prerendered. ## The reads that actually flip a parameterised route - The **cookie jar** — personalising the page for the signed-in visitor. - **Request headers** — localising by `Accept-Language`, branching on `User-Agent`, checking `Authorization`. - The **caller's address** — geolocating prices or availability. - The **query string** — as above. Note what is *not* on that list: looking up the record for the path parameter. That read is keyed by the URL, which is the same for everyone, so it stays static. ## Why the confusion is expensive Two failure directions, both common in review: 1. **Assuming parameterised means per-request.** A team renders a 40,000-page catalogue on every view because "the route is dynamic", paying for renders that could have been cache hits on shared infrastructure. 2. **Assuming a fixed path means shareable.** A single-URL account page is left in the prerendered set by configuration, and every visitor sees whichever user happened to be rendered first — the worst class of bug this area produces, because it leaks one person's data to everyone. The second is why enforcement matters: a route whose output *is* shared but whose content *is not* shareable is a correctness bug, not a performance one. ## The check to apply 1. Ask what varies across the URLs this route serves. If only the path, the route can be prerendered per value. 2. Ask what varies across two visitors at the **same** URL at the same instant. If anything does, the route is per-request. 3. If the answer to (2) is "just a small personal badge", consider keeping the route static and fetching that part in the browser instead of moving the whole route to per-request rendering. Enumerating which parameter values get prerendered, and what happens to a path nobody listed, belongs to the build-time prerendering discussion; here the point is only that the parameter itself is not what makes a route dynamic. ## Reading a route file honestly The route's file name tells you which URLs it answers and nothing about how it is rendered. To classify it you have to read the render, and the render includes every layout wrapped around it and every module those pull in. A page whose own code reads only its path parameter can still be per-request because a shared wrapper reads a cookie, and a page whose file name is full of parameters can be entirely static. - **Parameter in the path, no request reads** — static, one stored output per value. - **Fixed path, reads a cookie** — per-request, despite having no parameters at all. - **Parameter in the path, reads the query string** — per-request, because the query is visitor intent rather than identity. Those three lines are the whole distinction, and they are worth being able to produce on demand, because most arguments about a route's cost turn out to be an argument about which of the two senses of the word someone meant.
- Why is the query string usually treated as request state when the path is not?Because it is unbounded and expresses intent rather than identity. Path values can be enumerated from a data source and prerendered one file each, while sort, filter and pagination combinations multiply beyond anything you could produce ahead of time, and two visitors at the same path usually want different views.
- What is the danger of forcing a route with a fixed path into the prerendered set?If its content is actually per-visitor, one render is shared by everyone — the first visitor's data can be served to the next. That is a correctness and privacy bug rather than a performance one, and it is the reason frameworks would rather reclassify or fail than quietly prerender a request-bound render.
saying these in an interview costs you the question
- Says a parameterised route can never be prerendered.
- Treats the query string as identity, like the path.
- Thinks a fixed URL is automatically safe to prerender.
- Confuses the URL pattern with what the render reads.
- Assumes reading the record for a path parameter is request-bound.