Skip to main content

Development Process

DEVELOPMENT.md — OnCue Support Site (Current State)

This document describes how the project works today from a development and workflow standpoint (local usage). It covers the Docusaurus docs site, Decap CMS authoring/preview, the Streamlit builder, and the shared custom MDX “blocks” system. It does not cover future remote hosting plans.


1. What this project is

  • A Docusaurus “docs-only” site where docs are served at the site root.
  • Documentation is authored in MDX and stored in a structured folder layout.
  • Authors can create/edit pages via:
  1. direct edits to MDX files
  2. Decap CMS at /admin (with custom preview rendering)
  3. a Streamlit builder that generates MDX and provides an HTML preview

Key configuration:

  • site/docusaurus.config.js

2. How to run locally

2.1 Run the docs site (dev)

From the repo root:

npm run site:dev

This runs:

  • cd site && npm run start

Then open the URL printed by Docusaurus (commonly http://localhost:3000).

2.2 Build the docs site

From the repo root:

npm run site:build

This runs:

  • cd site && npm run build

2.3 Run the Streamlit builder

From the repo root:

streamlit run src/support_page_builder.py

Then open the URL printed by Streamlit (commonly http://localhost:8501).


3. Docusaurus configuration (current behavior)

In site/docusaurus.config.js:

  • Docs-only mode is active:
  • routeBasePath: '/' (docs are served at /)
  • Mermaid support is enabled:
  • markdown: { mermaid: true }
  • themes: ['@docusaurus/theme-mermaid']
  • Local search is enabled with @easyops-cn/docusaurus-search-local and is configured for docs-only mode:
  • docsRouteBasePath: "/"

4. Content structure (MDX docs)

4.1 Where docs live

Docs are stored under:

  • site/docs/<category>/<slug>.mdx

Current category folders:

  • documents
  • audiovisuals
  • transcripts
  • designations
  • media-scripts
  • notebooks
  • general
  • hidden (drafts)

4.2 Sidebar behavior

site/sidebars.js uses per-category autogenerated sidebars with dirName matching each folder.

Effect:

  • Adding a file in site/docs/<category>/... will generally add it to that category’s sidebar automatically (based on Docusaurus autogenerated rules).

4.3 Category landing pages (do not appear as “extra docs” in the category list)

Landing pages are stored outside the autogenerated category folders:

  • site/docs/category-pages/<category>.mdx
  • frontmatter includes: slug: /<category>
  • site/sidebars.js links to the landing page using a doc link:
  • { type: "doc", id: "category-pages/<category>" }

5. Asset handling (images)

Decap CMS is configured to store images at:

  • site/static/img (media_folder: static/img)

And pages reference them via:

  • /img/... (public_folder: /img)

So an uploaded file such as:

  • site/static/img/example.png

is referenced in MDX as:

  • /img/example.png

6. Decap CMS workflow (authoring + preview)

6.1 Where Decap lives

  • Admin UI route: /admin
  • Config file: site/static/admin/config.yml

Important: config.yml is inside the site directory, so its relative folder paths like docs/documents correctly resolve to site/docs/documents.

6.2 Collections map to docs folders

Each Decap collection corresponds to one folder under site/docs/, for example:

  • documentsdocs/documents
  • audiovisualsdocs/audiovisuals
  • hiddendocs/hidden

Each collection:

  • creates .mdx files (extension: mdx)
  • uses frontmatter format (format: frontmatter)
  • has fields:
  • title (required)
  • slug (optional)
  • tags (optional)
  • template_buttons (optional; templateCopy widget)
  • body (markdown widget; Markdown + MDX allowed)

6.3 How Decap “Preview” works (critical detail)

Decap preview is not a real MDX runtime. It is a custom renderer that approximates MDX by:

  • converting markdown to HTML
  • converting Docusaurus admonitions (:::note, :::caution, etc.) into HTML
  • scanning the body for custom component tags like <ImageBlock ...> and rendering them via a registry

Preview implementation:

  • site/static/admin/preview-templates.js

Implication:

  • If something renders correctly in the Docusaurus site but not in Decap Preview, it’s often a preview-renderer limitation rather than a content issue.

7. Streamlit builder workflow

The Streamlit builder:

  • provides a UI to assemble pages using the project’s block patterns
  • outputs MDX suitable for site/docs/...
  • shows an HTML preview styled to match the site as closely as possible

Run command:

streamlit run src/support_page_builder.py

Typical workflow:

  1. Build content in Streamlit
  2. Copy the generated MDX
  3. Paste into a .mdx doc under site/docs/<category>/...
  4. Validate via npm run site:dev
  5. Commit changes

8. Custom Blocks system (MDX components)

8.1 Runtime blocks (Docusaurus)

React block components are implemented in:

  • site/src/components/blocks/index.tsx

They are made available to MDX through:

  • site/src/theme/MDXComponents.js (generated)

Blocks are used in MDX like:

<ImageBlock image="/img/example.png" imageAlt="Example alt text">
Caption text here
</ImageBlock>

Important convention:

  • ratio is deprecated; use firstCol.
  • ImageBlock caption text should be inside the component body (between opening/closing tags).

8.2 Shared CSS (runtime + both previews)

Shared blocks CSS:

  • site/static/shared/oncue-blocks.css

This same file is loaded in:

  • Docusaurus runtime (via site/src/theme/Root.js)
  • Decap preview (CMS.registerPreviewStyle('/shared/oncue-blocks.css'))
  • Streamlit preview (via the app’s PREVIEW_CSS_URL mechanism)

The CSS defines common visual tokens such as:

  • --oc-block-space

9. Decap preview block registry + generation system

9.1 Why this exists

Because Decap preview is regex-based (not true MDX), it needs its own mapping of:

  • block name → how to render a preview HTML version of that block
  • whether a block can contain nested components (containers)

9.2 Single source of truth for blocks metadata

Block metadata lives in:

  • tools/blocks/blocks.manifest.json

A generator script:

  • tools/blocks/generate-blocks.mjs

…generates:

  • site/static/shared/blocks-config.generated.js (metadata exposed as window.ONCUE_BLOCKS_META)
  • site/src/theme/MDXComponents.js (runtime MDX component registration)

9.3 Decap preview rendering pieces

Decap preview uses three scripts (loaded by site/static/admin/index.html):

  1. site/static/shared/blocks-config.generated.js
  • provides metadata as window.ONCUE_BLOCKS_META
  1. site/static/shared/blocks-renderers.js
  • hand-written HTML rendering functions per block for preview
  1. site/static/shared/blocks-config.js
  • merges meta + renderers into window.ONCUE_BLOCKS

Important implementation note:

  • Use window.ONCUE_BLOCKS = ... (not a non-reassignable constant) to avoid assignment errors.

9.4 Nested components: allowNested

Container blocks (blocks that contain other blocks) must set:

  • allowNested: true

In the preview renderer, this enables recursive component rendering inside the container (rather than treating the inner content as plain markdown).

Examples:

  • ImageGridBlock → contains ImageGridItem
  • TwoColBlock → contains Col

10. Known layout/CSS constraints (current state)

  • Sidebar collapse behavior can break if sidebar widths are forced with !important. Prefer Docusaurus/Infima variables (e.g. --ifm-doc-sidebar-width) rather than hard-coded widths.
  • Admonitions use hashed CSS module classnames; overrides are done via attribute selectors like [class^="admonition_"] when needed.
  • Infima sets tables to display: block; overflow: auto; by default, which can break tables inside flex column layouts. A scoped override is applied inside the TwoCol layout so tables fill the column.

11. Common workflows (step-by-step)

11.1 Add a new doc page

Option A (direct MDX):

  1. Create site/docs/<category>/<slug>.mdx
  2. Add frontmatter title: ...
  3. Run npm run site:dev

Option B (Decap):

  1. Visit /admin
  2. Select the collection (category)
  3. Create entry → fill Title, optional Slug, edit body
  4. Save

Option C (Streamlit):

  1. Run Streamlit builder
  2. Assemble content
  3. Copy generated MDX into site/docs/<category>/<slug>.mdx
  4. Validate with npm run site:dev

11.2 Add or change a block

  1. Update/create the React component in site/src/components/blocks/index.tsx
  2. Update block metadata in tools/blocks/blocks.manifest.json (set allowNested: true for container blocks)
  3. Run the blocks generator (project command: npm run gen-blocks, if present in your scripts)
  4. Update site/static/shared/blocks-renderers.js if Decap preview needs new/changed HTML rendering
  5. Validate in:
  • Docusaurus runtime (npm run site:dev)
  • Decap preview (/admin)
  • Streamlit preview (if the builder supports that block)