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:
- direct edits to MDX files
- Decap CMS at
/admin(with custom preview rendering) - 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-localand 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:
documentsaudiovisualstranscriptsdesignationsmedia-scriptsnotebooksgeneralhidden(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.jslinks to the landing page using adoclink:{ 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:
documents→docs/documentsaudiovisuals→docs/audiovisuals- …
hidden→docs/hidden
Each collection:
- creates
.mdxfiles (extension: mdx) - uses frontmatter format (
format: frontmatter) - has fields:
title(required)slug(optional)tags(optional)template_buttons(optional;templateCopywidget)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:
- Build content in Streamlit
- Copy the generated MDX
- Paste into a
.mdxdoc undersite/docs/<category>/... - Validate via
npm run site:dev - 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:
ratiois deprecated; usefirstCol.ImageBlockcaption 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_URLmechanism)
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 aswindow.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):
site/static/shared/blocks-config.generated.js
- provides metadata as
window.ONCUE_BLOCKS_META
site/static/shared/blocks-renderers.js
- hand-written HTML rendering functions per block for preview
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→ containsImageGridItemTwoColBlock→ containsCol
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):
- Create
site/docs/<category>/<slug>.mdx - Add frontmatter
title: ... - Run
npm run site:dev
Option B (Decap):
- Visit
/admin - Select the collection (category)
- Create entry → fill Title, optional Slug, edit body
- Save
Option C (Streamlit):
- Run Streamlit builder
- Assemble content
- Copy generated MDX into
site/docs/<category>/<slug>.mdx - Validate with
npm run site:dev
11.2 Add or change a block
- Update/create the React component in
site/src/components/blocks/index.tsx - Update block metadata in
tools/blocks/blocks.manifest.json(setallowNested: truefor container blocks) - Run the blocks generator (project command:
npm run gen-blocks, if present in your scripts) - Update
site/static/shared/blocks-renderers.jsif Decap preview needs new/changed HTML rendering - Validate in:
- Docusaurus runtime (
npm run site:dev) - Decap preview (
/admin) - Streamlit preview (if the builder supports that block)