Architecture & Engineering

Why we build route families instead of copying pages

How one tested route template can power services, locations, articles, products, case studies, and documentation without turning every new page into a new maintenance problem.

A website with thirty pages does not necessarily need thirty page implementations. When several pages share the same job, we build a route family and give each page its own content. That distinction is one of the biggest differences between a site that scales cleanly and a site that becomes harder to maintain every time another page is added.

A service page is a type of page

Imagine a business with eight services. Those services may need different titles, descriptions, images, FAQs, proof points, and SEO metadata, but they probably share a recognizable structure. They still need a page heading, hero, content sections, calls to action, breadcrumbs, schema, and related navigation.

Copying the first service page seven times feels fast on day one. It creates eight implementations that can drift on day ninety. A route such as /services/[slug] lets us define the page behavior once and load a different service model for each slug.

We use this pattern across very different projects

One contractor build generates its service routes by calling a server-side getAllServices() function and returning every service slug through generateStaticParams(). The route then uses the selected service to build metadata, breadcrumbs, FAQ schema, service schema, and the actual page interface. A separate local-service build does the same thing for location pages. Its location content model includes the city, hero asset, about copy, service summaries, FAQs, and SEO fields. The route generator does not care which city it is rendering. It cares that the content satisfies the location model.

Another project uses the filenames in a case-study MDX directory as the route registry itself. If the file is valid, a static route can be generated for it. Different codebases, same architectural idea.

The benefit is not fewer files

We are not trying to win a contest for the smallest repository. The benefit is that shared behavior stays shared. If we discover that service pages need a better breadcrumb implementation, we fix the service route. If article pages need a new metadata field, we update the article loader and template. If location pages need better related-area navigation, we change that system once.

The content files remain independent, which is where the page-specific differences belong.

It makes QA much more valuable

Testing one route template thoroughly gives us confidence across every page that uses it. That does not mean every content instance is automatically correct. A specific MDX file can still have a bad image or weak copy. But layout, semantic structure, schema rendering, responsive behavior, and common metadata logic are not reimplemented from scratch for every page.

QA effort compounds instead of resetting.

It also prevents accidental SEO differences

Copied pages have a habit of keeping stale values. A canonical from the first page remains on the second page. An old service name survives in structured data. A social image points to the wrong file. A title template gets edited on five pages but not the sixth.

With a route family, canonical generation can be a function of the slug. Schema can be a function of the data model. The title can be derived from the page content. That does not make mistakes impossible. It makes whole categories of copy-paste mistakes less likely.

Route families do not justify thin content

This point matters. The fact that we can generate a hundred location pages does not mean we should. A dynamic route is an implementation technique, not a content strategy. If every location file contains the same paragraph with a city name swapped out, the site still has a quality problem.

We use a shared model so real differences can be expressed consistently. A useful location page can have its own local framing, project context, services, FAQs, images, and internal links while still using the same tested template.

The content model becomes part of the architecture

Once a route family exists, the content shape becomes a contract. A service may require a title, description, image, service details, and FAQs. A documentation page may require a category, order, description, and body. An article may require publication and modification dates.

This is why our MDX libraries often normalize and validate data before it reaches the component tree. The route should receive a trustworthy model rather than discovering halfway through rendering that a required field is missing.

Why this matters when the site reaches hundreds of pages

The first ten pages can survive almost any architecture. The real test comes later. If adding page 101 requires copying a React file, editing sitemap XML, adding metadata manually, updating three navigation arrays, and remembering which schema block to duplicate, the system does not scale.

If adding page 101 means creating a content file that satisfies an established model, reviewing it, and letting the build generate the route, metadata, sitemap entry, and shared layout, the system has leverage. That is the kind of leverage we want.

From explanation to proof

Where this connects to the work

This category is the clearest technical proof that our sites are built as maintainable software rather than assembled as isolated pages.