Unthought.

Information architecture

The route table is written and agreed before anything is designed, because page counts later become assertions the build enforces.

Site structure is usually discovered rather than decided. Pages accumulate as they are needed, a section grows a subsection, something gets duplicated because it was easier than reorganizing, and eighteen months later nobody can say how many pages the site has or which of them are load-bearing. The remedy is unglamorous: write the route table down first, and treat the number of pages as a decision.

Before anything is designed, we produce a written route table — every route, its slug, its parent, whether it is static or generated from data, and what job it does that no other page does. The document is short and it is boring, and it determines whether the project finishes on the terms it started on.

One page, one job. Two pages competing for the same query is a self-inflicted problem: it splits whatever authority the site has, confuses a reader who lands on the wrong one, and creates two places where the same fact can drift out of agreement. When two pages turn out to have the same job, they are merged and one redirects permanently to the other. When one page turns out to have two jobs, it is split.

The trade's own vocabulary decides the nouns. A law firm has practice areas; a remodeler has a portfolio; a manufacturer has product lines. Using a generic term where the industry has a specific one signals a template from the navigation bar onward, and it is one of the few structural mistakes a visitor registers in the first two seconds without being able to name it.

Routes generated from data are derived, never hand-listed. Where a set of pages comes from a configuration array, the framework generates the params from that array and refuses any path outside it. The slug union is computed from the data, so a page whose slug is not in the configuration fails to compile, and an entry in the configuration with no corresponding page fails the same way. A missing page becomes a build error, not a 404 discovered by a customer.

Because the route table was decided rather than accumulated, its counts can be asserted. The generated sitemap is compared against the decided number of routes, and a mismatch fails the build. This is only meaningful because the number was a decision in the first place — a count derived from whatever happens to exist can never disagree with itself. When the count legitimately changes, the constant changes with it, deliberately and in the same commit.

The highest-risk structural pattern in this work is the location matrix: one page template multiplied across a list of towns. Done carelessly it produces pages that exist only because a name could be substituted, which is a doorway pattern and is treated as one. The rule is that no location page ships without something true that is only true of that place, and the enforcement is a required configuration field with no default value — a page that cannot state a specific local fact cannot be generated at all. The check on top of it compares page bodies with the place names normalized out and fails when two are equivalent.

Bounding the matrix matters as much as populating it. A business that genuinely serves eight towns has eight pages; it does not have eight towns multiplied by twelve services. Where a matrix is warranted it is made deliberately asymmetric, because asymmetry is something a template cannot produce and is therefore evidence that decisions were made. The base city gets no combination pages at all, since they would compete with the main service pages for the same query.

Some sites should have no location tree whatsoever, and saying so is part of the work. A national practice, a firm whose clients do not care where it sits, a business whose service is delivered remotely — for each of these, a service-area section is pages that have nothing to say, and the honest recommendation is to cut them instead of to pad them.

URLs are treated as permanent once published. An address that has been given to anyone, printed anywhere, or indexed by anything is a commitment, and changing it without a redirect breaks every reference to it that exists outside the site. Where a restructure genuinely requires new addresses, the redirect map is written as part of the plan rather than assembled afterward from whatever the analytics report shows going missing.

Depth is capped deliberately. A route three levels down is a route most visitors will never reach and most crawlers will treat as marginal, so a fourth level has to justify itself against the alternative of flattening. Where a hierarchy genuinely runs deep, breadcrumbs carry the position, not the reader's memory of how they got there.

Navigation is derived from the route table rather than maintained beside it. A menu that is hand-written is a second copy of the site's structure, and two copies of a structure disagree eventually — usually by a link pointing at a page that was renamed, which nobody notices because the person who renamed it was not looking at the menu. Where the navigation is generated from the same data the pages are, that class of defect cannot occur.

The output of this phase is a document, and the test of the document is whether the site could be built from it by someone who was not in the conversation. If the route table cannot be written, the part that cannot be written is the part nobody has decided yet, and building around an undecided thing costs more than deciding it.

Exclusions

What this does not cover.

  • Location page matrices where the business cannot state something specific and true about each place.
  • Faceted or parameterized URLs that generate indexable combinations without editorial control.
  • Restructuring an existing site's URLs without a redirect map agreed in advance.