Extension Architecture
This page explains where framework code belongs in CrychicDoc and how to keep contracts, runtime logic, and rendering concerns separated.
Architectural Rule
Use this split consistently:
apiowns contract truthruntimeowns shared state and lifecycletheme/componentsowns renderingconfigowns project defaults and registration wiringdocs/**owns examples, user guides, and developer-facing documentation
Create a Standard Page
For a normal documentation page:
- Create the markdown file under the same relative path in both locale trees.
- Start with simple page frontmatter:
yaml
---
title: Example Page
layout: doc
description: What this page covers.
---- Add nav, docs-hub, or home-page entry points only if the page must be discoverable from those surfaces.
- If the page introduces a new contract or workflow, update the related developer doc in the same change.
Create a Home or Hero Page
For a landing page or developer hub page:
- Use
layout: home. - Define the hero contract before adding view-specific styling:
yaml
---
layout: home
hero:
name: Developer Docs
text: Extend CrychicDoc Safely
tagline: Runtime, frontmatter, plugins, and content registration
actions:
- theme: brand
text: Development Workflow
link: /en/doc/developmentWorkflow
---- Add
featuresorfeatureCardsonly after the hero structure is stable. - If the page becomes a primary entry point, update
docs/en/index.md,docs/zh/index.md, and the locale nav files in the same change.
Component Extension
When adding a new component:
- Place it under
.vitepress/theme/components/<category>/. - Export reusable ones through
.vitepress/utils/vitepress/componentRegistry/**. - Register markdown-facing ones in
.vitepress/utils/vitepress/components.ts. - Add locale resources if the component renders UI text.
- Keep component IDs and i18n mapping synchronized.
Register New Content
For content-style components that appear inside markdown pages or document chrome:
- Create the component in
.vitepress/theme/components/content/. - Export it from
.vitepress/theme/components/content/index.tswhen that barrel is used. - Export it from
.vitepress/utils/vitepress/componentRegistry/contentRegistry.tswhen theme internals should import it through the registry layer. - Register it in
.vitepress/utils/vitepress/components.tswhen markdown pages should reference it directly by tag name. - If it uses
useSafeI18n, add locale JSON files and keepcomponent-id-mapping.jsonaligned. - If it is emitted by a markdown plugin, make sure the plugin outputs a registered tag.
- Add at least one real markdown example page so the component is validated by the build.
Use this rule:
componentRegistry/contentRegistry.tsInternal reuse inside the theme.components.tsPublic markdown/global registration.
Function and Runtime Extension
When adding a composable, service, controller, or helper:
- Put pure normalization in
.vitepress/utils/vitepress/api/**. - Put shared stateful behavior in
.vitepress/utils/vitepress/runtime/**. - Export public entry points from the nearest
index.tsbarrel. - Prefer one shared runtime over many component-local observers.
Strong examples already in the repo:
- Theme sync:
.vitepress/utils/vitepress/runtime/theme/** - Hero nav adaptation:
.vitepress/utils/vitepress/runtime/hero/navAdaptiveState.ts - Frontmatter contract normalization:
.vitepress/utils/vitepress/api/frontmatter/hero/HeroFrontmatterApi.ts
Configuration Extension
Primary files:
.vitepress/config/project-config.ts.vitepress/config/lang/**.vitepress/config/markdown-plugins.ts.vitepress/config/shaders/**
Checklist:
- Define the field or registry entry.
- Normalize it in the API layer.
- Consume only normalized values in runtime or views.
- Add docs examples immediately.
- Run
yarn sync-configandyarn frontmatterwhen generated metadata depends on the change.
Style Extension
Follow the import layering in .vitepress/theme/styles/index.css.
- Scoped
<style>: component-local visuals - Global CSS under
.vitepress/theme/styles/**: shared tokens, plugin skinning, cross-component selectors - Frontmatter/config-backed CSS variables: theme-sensitive or runtime-sensitive values
Create a New Markdown Plugin
- Implement plugins in
.vitepress/plugins/**. - Register them in
.vitepress/config/markdown-plugins.ts. - Register any required rendering component in
.vitepress/utils/vitepress/components.ts. - Add usage pages under both locale trees.
If the plugin is meant to become a reusable authoring surface, also document:
- the markdown syntax
- the rendered component name
- frontmatter dependencies
- copy-paste-safe examples in both locales
File Ownership Table
- New hero field or nested frontmatter key:
.vitepress/utils/vitepress/api/frontmatter/** - Theme-ready lifecycle or observer logic:
.vitepress/utils/vitepress/runtime/** - New Vue block or visual surface:
.vitepress/theme/components/** - New markdown syntax:
.vitepress/plugins/**plus.vitepress/config/markdown-plugins.ts - New global token or shared skin:
.vitepress/theme/styles/** - New developer handbook page:
docs/en/doc/**anddocs/zh/doc/**