Skip to content

Architecture

The docs builder is a containerized Astro + Starlight system. Content repos provide Markdown/MDX files; the builder supplies the framework, theme, and build logic. The two halves meet at build time inside a Docker container.

Content repos keep their documentation in a docs/ directory. At build time the container copies those files into src/content/docs/, where Astro’s content collection picks them up.

content-repo/
docs/ ← authored by content teams
index.mdx
guide.mdx
docs-builder/
src/content/docs/ ← empty at rest (.gitkeep)

The entrypoint script (docker/entrypoint.sh) performs the copy:

Terminal window
cp -r "$CONTENT_DIR"/* /app/src/content/docs/

This means the builder repo itself ships with an empty src/content/docs/ directory. Content only appears at build time.

The Starlight theme is published as a separate npm package. package.json uses an npm alias to map a short name to the scoped registry package:

"@f5xc-salesdemos/docs-theme": "^1.29.0"

The theme package owns astro.config.mjs. At build time the entrypoint copies it into the project root:

Terminal window
cp /app/node_modules/@f5xc-salesdemos/docs-theme/astro.config.mjs /app/astro.config.mjs

This keeps configuration centralized — content repos and the builder itself do not maintain their own Astro config.

src/
components/
PlaceholderForm.tsx # React form for editing placeholder values
PlaceholderFormWrapper.astro # Astro wrapper, loads DOM script and global CSS
content/
docs/ # Mount point for injected content
content.config.ts # Starlight content collection definition
data/
placeholders.json # Placeholder token definitions
lib/
placeholder-store.ts # State management: load, save, compute, emit
scripts/
placeholder-dom.ts # Client-side DOM walker and Mermaid renderer

src/content.config.ts defines a single docs collection using Starlight’s loader and schema:

import { defineCollection } from 'astro:content';
import { docsLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
};

Any .md or .mdx file placed in src/content/docs/ becomes a page in the built site.

The following diagram shows the end-to-end build pipeline when the Docker container runs:

flowchart LR
    A[Content Repo<br/>docs/] -->|mount| B[Container<br/>/content/docs]
    B -->|entrypoint.sh<br/>cp| C[src/content/docs/]
    D[npm registry] -->|npm install| E[node_modules/<br/>@f5xc-salesdemos/docs-theme]
    E -->|cp astro.config| F[astro.config.mjs]
    C --> G[astro build]
    F --> G
    G --> H[dist/<br/>static HTML]
    H -->|cp| I[/output]
ConcernWhenHow
MDX → HTMLBuild timeAstro compiler
Mermaid code blocks → container divsBuild timeremark-mermaid.mjs plugin (from docs-theme)
Placeholder tokens → interactive spansClient timeplaceholder-dom.ts TreeWalker
Mermaid SVG renderingClient timemermaid CDN import in placeholder-dom.ts
Placeholder form stateClient timeplaceholder-store.ts + localStorage
Astro page transitionsClient timeastro:page-load event listener