Skip to Content
ConventionsPage naming

Page naming

This page is the live, in-site form of the docs naming convention. If you’re authoring a new page, this is the reference. The same content lives in the repo as docs/specs/002-docs-naming-convention/contracts/naming-convention.md — that file is the source of truth; this page renders the same rules so you can read them in context.

Why titles look the way they do

Every page title follows the pattern <Context>: <Leaf>. The prefix isn’t decoration — it answers “what zone is this in?” in every context that strips away the sidebar: search results, chatbot citations, browser tabs, link previews. Without it, a reader landing cold has to do mental indexing on every page view. With it, the title alone locates the page.

The on-page # Heading may drop the prefix — the sidebar already shows the reader where they are.

Quick reference: title prefixes

Audience zones

Where pages liveTitle prefixExample
app/overview/<module>/page.mdxOverview:Overview: Skill levels
app/business-logic/<module>/page.mdxBusiness logic:Business logic: Member lifecycle

Component zones (one per deployable)

Where pages liveTitle prefixNotes
app/api/<...>/page.mdxAPI:Backend service. Per-service / per-tag pages are generated by docs/scripts/openapi-to-mdx.ts from Bruno collections and emit their own titles; the rule applies to authored MDX (index, conventions, getting-started).
app/www/<...>/page.mdxWWW:The Express/Backbone public site.
app/admin/<...>/page.mdxAdmin:The Next.js admin dashboard.
app/mobile/<...>/page.mdxMobile:The mobile app (separate repo).
app/assistant/<...>/page.mdxAssistant:The TunnelFlight Assistant (separate project).
app/integrations/<provider>/page.mdxIntegration:Third-party systems we connect to (Fuzemetrix, Convergence, Tunn3l).

Cross-cutting zones

Where pages liveTitle prefixNotes
app/common-tasks/<action>/page.mdxCommon task:Operational runbooks. Slug MUST start with a verb.
app/infra/<module>/page.mdxInfra:Genuine platform infrastructure (CI, data storage, request patterns, architecture). Not a catch-all — if content doesn’t fit a component or audience zone, prefer a new zone over expanding infra/.
app/conventions/<topic>/page.mdxConvention:Meta-docs about how we work — like this page.

Utility routes (exempt)

/, /changelog, and /graph are single-page utilities. They have a title: but no archetype prefix.

Slug rules

Directory names become URL fragments. They MUST:

  1. Match ^[a-z0-9]+(-[a-z0-9]+)*$ — lowercase ASCII, hyphen-separated.
  2. Not start with a numeric prefix (01-foo, 02-bar). Ordering belongs in _meta.tsx.
  3. Use full English words OR an acronym from the allow-list: api, www, db, oauth, sso, c4, pwa, mfa, jwt, cdn, ci.
  4. For common-task pages: start with a verb (add-, update-, remove-, enable-, disable-, configure-, rotate-, migrate-, …) so the URL itself tells the reader what the page does.

Labels in _meta.tsx SHOULD:

  • Drop the archetype prefix — the sidebar’s tree position already supplies it.
  • Be concise (typically 1–3 words).
  • Be parallel within a section (same voice, same length).

Example — app/overview/_meta.tsx:

export default { 'platform-at-a-glance': 'At a glance', 'members': 'Members', 'skill-levels': 'Skill levels', 'tunnels': 'Tunnels', }

The frontmatter title (Overview: Skill levels) and the sidebar label (Skill levels) deliberately differ.

Legacy pages

Pages preserved for historical reference MAY keep their existing titles but SHOULD gain a Legacy · prefix:

title: "Legacy · API: Status codes"

No new pages should be added under a (legacy) directory.

Redirects

When you rename a slug or move a page between zones, you MUST add a corresponding entry to docs/next.config.mjs:

{ source: '/old/path/here', destination: '/new/path/here', permanent: true, }

This is non-negotiable — bookmarks must not silently break. For sub-tree moves, use Next.js wildcard syntax (source: '/old/:path*').

Authoring a new page

  1. Pick the right archetype + zone from the tables above.
  2. Copy the matching template from docs/_templates/:
    • overview.mdx
    • business-logic.mdx
    • common-task.mdx
    • component.mdx (works for any component, integration, infra, or convention page — pick the prefix per the comment block in the file)
  3. Replace the REPLACE placeholders.
  4. Add an entry to the parent _meta.tsx for the sidebar.
  5. Run npm run audit-naming from docs/ to catch any non-conformance before opening the PR.

Enforcement

  • At authoring time: copy from docs/_templates/.
  • At review time: npm run audit-naming reports any non-conformance with a specific reason.
  • At CI time: not enforced today. Lifting the audit into CI is a one-line follow-up if manual review proves insufficient.

Adding a new zone

The convention’s appendix lists the 13 top-level zones. Adding a new one is a deliberate act — update:

  1. docs/specs/002-docs-naming-convention/contracts/naming-convention.md §3 and Appendix
  2. docs/specs/002-docs-naming-convention/data-model.md Zone vocabulary table
  3. docs/scripts/audit-naming.ts zone-prefix constants
  4. This page

The friction is intentional — every zone earns its slot.

Adding a new infra/ module

infra/ is deliberately narrow. Adding a module requires justifying in the PR description why the content belongs to platform infrastructure rather than a component or audience zone. This friction is intentional — infra/ previously absorbed unrelated content under its old tech/ name, and the convention is designed to prevent that recurring.

Last updated on