For a route with a dynamic path segment, how does the build decide which concrete paths to prerender?
answer
- the build cannot guess a dynamic value
- a list of parameter sets
- same data that fills the pages
- one entry, one emitted file
- filter the list to bound the build
basics
~20 sA dynamic segment has no fixed path list, so the route supplies a build-time enumeration step returning the parameter sets to render — usually a query against the data source that fills the pages. The build emits one page per entry.
solid answer
~50 sA dynamic segment is a placeholder, and the build cannot guess what belongs in it, so a prerenderable dynamic route has to declare an enumeration step that runs first and returns a list of parameter sets: every published article slug, every product id, every file in a content directory. That list usually comes from the same source the page reads, so it is typically a cheap listing query. The build then renders and writes one page per entry, so the list is literally the build's unit of work — its length sets the build's duration and the output's size. Nested dynamic segments need care: enumerating a parent and a child independently produces the cross product, so the enumeration should return valid combinations. And the list is meant to be filtered — prerendering the valuable slice and leaving the tail to another mode is the normal way to keep a build bounded.
go deeper
Remember that a dynamic segment needs an explicit list before it can be prerendered, and that the list normally comes from the same data that fills the pages.
Explain the mechanism end to end: enumeration runs first, returns parameter sets, and the build renders one page per entry — so the list length is the build's workload.
Show that you treat the list as a filter with a cost attached, guard against empty or non-deterministic enumerations, and know what requests for paths outside the list will meet.
Own the policy question: which slice of a growing catalogue is worth build-time cost at all, who decides it, and how the build budget is monitored as the data grows.
A route with a **dynamic segment** — a path position that stands for a value rather than a literal, such as an article slug or a product id — describes a family of pages, not one page. Prerendering it at build time therefore needs an extra input that a fixed route does not: the list of concrete values to render. ## Why the build has to be told The set of valid values lives in data, not in code. The router knows the *shape* of the path; only the data source knows that there are 812 published articles and what their slugs are. There is no request traffic to learn from either, because the build runs before anyone visits. So every meta-framework that prerenders dynamic routes exposes the same mechanism under different names: **a build-time function, attached to the route, that returns the parameter sets to prerender**. A typical enumeration does one of these: - queries the content service or database for the listable set (`published = true`, `deleted_at is null`); - lists a content directory on disk and derives one entry per file; - reads an already-built index or sitemap-like manifest produced earlier in the pipeline; - returns a hard-coded list, which is perfectly reasonable for a small, slow-moving set. ```pseudocode enumerate() -> [ {slug: "a"}, {slug: "b"}, ... ] for params in enumerate(): data = load(params) # the route's own data loading write(path(params), render(data)) ``` ## The list is the build's unit of work Everything downstream scales with its length: | The list grows | What grows with it | |---|---| | 100 entries | A short build, a small output directory | | 10,000 entries | Build duration, one data fetch per entry, output size | | 100,000 entries | Deploy upload time, and the practicality of rebuilding at all | That makes filtering a design decision, not an optimisation. Common filters: only published items; only items in the primary locale; only the top slice by traffic or recency; only items whose page is actually linked. What is left out is not lost — it is handled by whatever the route does for a path the build did not produce. ## Nesting and combinations When a path has two dynamic segments — a category and an item inside it, say — enumerating each independently and letting the build combine them produces the **cross product**, including combinations that do not exist. Three symptoms follow: a build far longer than the real page count, pages that render an empty or error state, and those pages being linkable and indexable. The fix is to enumerate the pairs that exist, in one query, rather than two lists. ## Failure modes worth naming in an interview 1. **An empty list passing silently.** If the enumeration query returns nothing — wrong credentials at build time, a filter that excludes everything — the build may succeed and emit zero pages of that family. Assert on a plausible count in the build so this fails loudly. 2. **Non-determinism.** Two builds from the same commit should produce the same page set; an enumeration that depends on wall-clock time or ordering makes deploys hard to reason about. 3. **Duplicates and unsafe values.** Values that differ only by case, by trailing whitespace, or by characters that need escaping in a path collide once they become file names; deduplicate and normalise in the enumeration. 4. **An enumeration that is as expensive as the pages.** Fetching every entity in full just to read its id turns a listing query into the build's bottleneck. Ask for the key fields only. 5. **Drift after the build.** Anything added to the data source after the enumeration ran is simply not in this build's output, whatever the data source says now. ## The relationship with the rest of the render modes The enumerated list draws a line through the route's path space: inside it, requests are served from files; outside it, the route falls back to whatever the framework has been configured to do for an unknown path. Treating the list as a knob rather than as "all of them" is what keeps a large catalogue's build inside a sensible window while the pages that matter still ship prerendered.
- What happens to entries added to the data source after the build enumerated it?They are not in this build's output. Until a new build runs, requests for them fall through to whatever the route does for an unknown path — a not-found response, a render on demand, or a placeholder shell, depending on how the route is configured.
- Should the enumeration reuse the route's per-page data loading?No — keep them separate. Enumeration only needs the key fields that form the path, so it should be a cheap listing query; fetching every entity in full to read its id makes the listing as expensive as the whole render pass.
- How do you keep a build from silently emitting zero pages for a route family?Assert on the enumeration's result inside the build: fail when the list is empty, or when its length falls far below the last known count. An empty list is usually a credentials or filter problem, and without an assertion it looks like a successful build.
saying these in an interview costs you the question
- Assumes a dynamic route prerenders with no list of paths supplied at all
- Thinks the enumeration runs per request rather than during the build
- Enumerates every row in a table without asking what the build will cost
- Lets two nested segments form a cross product of non-existent combinations
- Expects entries added after the build to appear without a rebuild
- Treats an enumeration returning zero entries as a successful build