DocHub
How /docs/ routes render HTML pages from markdown with sidebar navigation

Documentation Routes

DocHub serves content through two route families: /overview/ for Tier 1 visual HTML pages and /docs/ for Tier 2 rendered markdown. This page covers both.

Overview Routes (Tier 1)

The /overview router (routes/overview.ts) serves self-contained HTML pages with embedded CSS — no template wrapping.

Route Purpose
GET /overview/ Hub landing page showing all three tiers with navigation
GET /overview/:id Individual overview page read from content/_overviews/{id}.html

Overview pages are registered in a static list within the route handler. Adding a new overview requires:

  1. Creating the .html file in content/_overviews/
  2. Adding its metadata (id, title, subtitle) to the overviewPages array in routes/overview.ts

The root URL / redirects to /overview/ — making the hub the primary entry point.

Docs Routes (Tier 2)

The /docs router (routes/docs.ts, 198 lines) serves rendered markdown pages. It handles four URL patterns plus search.

Route Patterns

Search — GET /docs/search?q=term

Calls markdownService.searchContent(q) and renders results using templateService.renderDoc() with a custom HTML results list. Empty query redirects to /docs/.

Hub Home — GET /docs/

First checks for _master/index.md in the content root. If found, renders it as a full doc page (with TOC and sidebar). Otherwise, lists all projects as cards using templateService.renderIndex().

The _master/index.md approach means the hub landing page is itself a markdown file that can be edited like any other document.

Project Index — GET /docs/:project/

Lists all subprojects within a project as cards. Reads _project.yaml for the project display name. Returns 404 if the project has no subprojects.

Subproject Index — GET /docs/:project/:subproject/

First checks for index.md within the subproject directory. If found, renders it as a full doc page. Otherwise, lists all pages as cards. Returns 404 if no pages exist.

Individual Page — GET /docs/:project/:subproject/:page

The main document renderer. Process:

  1. Check for ?format=raw query param — if present, return raw markdown with text/markdown content type
  2. Call markdownService.renderPage() to parse frontmatter and render HTML
  3. Build breadcrumb chain: DocHub > Project > Subproject > Page
  4. Call templateService.renderDoc() to wrap content in the full layout

Returns 404 if the .md file doesn’t exist.

Page Layout

Every rendered page includes:

  • Header bar — dark background, brand link, nav links (Home, API, Report), search input
  • Sidebar — left panel (280px) with collapsible nav sections built from markdownService.getNavTree()
  • Breadcrumbs — path from DocHub root to current page
  • Summary — optional subtitle from frontmatter, shown in muted text below breadcrumbs
  • Content — rendered markdown HTML in a max-width 800px container
  • TOC — right-side “On this page” panel (h2/h3 headings, fixed position, hidden below 1200px)

The sidebar shows all projects and their subprojects. When viewing a page within a subproject, that subproject’s individual pages expand as indented links below the subproject heading. The current page gets the .active class (blue left border).

Search Flow

The search input in the header uses an onkeydown handler. Pressing Enter navigates to /docs/search?q=.... The search route calls markdownService.searchContent() which does a recursive filesystem walk — no database or index involved.