The /kb/ Browser — Markdown to UI Pipeline
Status: Active
Last Updated: 2026-08-26
Category: fogserv - Project Reference
Prerequisites: architecture-overview, ../frontend/tanstack.md
Time: 20 min read
Tags: fogserv, kb, markdown, vite-glob, react-markdown, prerendering, tanstack-router
Summary
How the knowledge base you're reading gets into fogserv.cloud: src/routes/kb_.$.tsx glob-imports every file under /kb/**/*.md as raw strings at build time via Vite's import.meta.glob, parses frontmatter with a small regex parser, and renders articles with react-markdown + GFM. Directory slugs map to README files. No database, no runtime file reads.
Context / Why This Matters
Editing a KB article changes what the website serves only after an image rebuild (deployment-runbook). Understanding this pipeline explains why: the KB is compile-time content, not CMS content. It also matters for authoring — certain frontmatter keys drive the index page, and link style inside articles affects rendering.
Implementation / Core Content
Pipeline stages
kb/**/*.md ──import.meta.glob(?raw)──► slugToContent map ──react-markdown──► /kb/<path> pages
(repo) (build time) (module scope) (render time)
Glob import (
kb_.$.tsx, module scope):const mdFiles = import.meta.glob('/kb/**/*.md', { eager: true, query: '?raw' })eagerinlines every article into the bundle; nothing is fetched at request time.Slug map construction: paths like
/kb/networking/wireguard-setup.mdbecome slugsnetworking/wireguard-setup. A file namedreadme.md(any case) additionally registers its parent-directory slug, so/kb/networking/rendersnetworking/README.md.Frontmatter parsing: regex over the leading
---block into{ title?, description?, ... }. The KB index (kb.index.tsx) lists articles from these fields — keeptitleaccurate; it's what readers see before clicking.Rendering: frontmatter stripped (
cleanBody), body passed toReactMarkdown+remark-gfm.
Authoring implications
- Relative links between articles work because the splat route preserves directory structure — prefer
.md-suffixed relative links (../cicd/rollback-procedures.md) matching the repo layout. - Adding an article = adding a file; it appears after next build+deploy. No registration step.
- Renaming/moving files breaks inbound relative links — grep
](old-nameacrosskb/first. - Very large articles bloat the JS bundle since everything is eager-loaded; keep articles focused (~5–15KB).
Route anatomy
src/routes/kb.index.tsx— index listing (frontmatter-driven cards)src/routes/kb_.$.tsx— splat route;params._splatholds the path slug
Practical Examples
Publish this article's changes: edit files under kb/, then git push → CI builds image → deploy workflow ships it → verify https://fogserv.cloud/kb/fogserv/kb-browser.
Check a slug locally: run bun run build; Vite logs or a quick node REPL against dist/ output confirm which slugs registered. A 404 at /kb/x/y almost always means filename/slug mismatch (case sensitivity counts).
Common Pitfalls & Troubleshooting
- New article 404s on the site but exists in repo — site wasn't rebuilt/redeployed; KB is build-time static.
- Index shows wrong/missing title — malformed frontmatter (regex needs
key: valuelines under---); YAML features like nested structures are NOT supported by the mini-parser. - Broken links render literally — check for extensionless or absolute-style links; use repo-relative
.mdpaths. - Case-sensitivity traps —
Readme.mdworks as a dir index (lowercased check) butREADME.MDmay not match the glob expectations consistently; stick toREADME.md. - Mermaid/HTML in articles — react-markdown escapes raw HTML by default; don't rely on embedded HTML rendering.
Next Steps / Ops Actions
- When KB grows large enough that eager-loading hurts build/bundle size, consider lazy per-article chunks (
import.meta.globwithouteager) — note the current sync map exists specifically so prerendering stays clean.
Sources & Related Articles
- Source:
src/routes/kb_.$.tsx,src/routes/kb.index.tsx - Related: architecture-overview, deployment-runbook, ../frontend/routing-patterns.md
Change Log
2026-08-26
- Initial creation from source inspection of kb_.$.tsx