Set up and author a documentation site with @lobehub/docs-kit (the `lobedocs` CLI, React Router + Vite static docs used by ui.lobehub.com). Covers consumer repo layout, docs.config.ts, package scripts, component doc pages (index.mdx frontmatter, `?demo` imports, <Demo>, <Api>), guide pages, home page, changelog, and the build-time validations that reject bad docs. Trigger on docs-kit, lobedocs, defineDocsConfig, docs.config.ts, migrate from dumi, write component docs, add a demo, <Demo>, <Api>, index.mdx, 文档站, 写文档, 组件文档, 迁移 dumi.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
The consumer repo holds only content + docs.config.ts. The kit owns Vite and React Router
config; do not add vite.config.ts or react-router.config.ts unless overriding (see
reference/config.md).
lobe-ui itself is the reference consumer: docs.config.ts, docs/, src/*/index.mdx,
src/*/demos/.
<repo>/
├── docs.config.ts # defineDocsConfig({...}) — required
├── package.json # lobedocs scripts
├── docs/
│ ├── index.mdx # "/" — required (frontmatter feeds SEO even with a custom homePage)
│ ├── changelog.mdx # "/changelog" — optional; else root CHANGELOG.md is used
│ └── home/home.tsx # optional custom landing page (config.homePage)
├── src/
│ └── Button/
│ ├── index.ts # barrel export — <Api> resolves props through it
│ ├── Button.tsx
│ ├── type.ts # props with JSDoc
│ ├── index.mdx # -> /components/button
│ └── demos/
│ ├── index.tsx # default-export component
│ └── Variant.tsx
├── public/ # static assets served at "/" (favicons, og images)
└── CHANGELOG.mdHard rules the compiler enforces:
index.mdx under an atomDirs root become component pages
(index.md and README.md are ignored).src/**/demos/** — standalone /~demos/:id routes and
isolated demos are globbed from that path only.docs/**/*.mdx files are not discovered unless listed in publicDocs.pnpm add -D @lobehub/docs-kit @react-router/dev@8.2.0 react-router@8.2.0 vite@8.1.4 tsx
pnpm add react react-dom # ^19{
"scripts": {
"docs:dev": "lobedocs dev",
"docs:build": "lobedocs build",
"postinstall": "lobedocs typegen"
}
}lobedocs build writes the static site to dist/ (Pagefind search, sitemap, /llms.txt,
/skills.md are generated automatically). Node >= 22.22.
docs.config.tsexport default {
atomDirs: [{ dir: 'src' }],
title: 'Lobe Editor',
description: 'One sentence describing the library.',
siteUrl: 'https://editor.lobehub.com',
alias: { '@': 'src', '@lobehub/editor': 'src' }, // let demos import the package from source
themeConfig: {
apiHeader: {
packageName: '@lobehub/editor', // defaults to @lobehub/ui — always set it
github: 'https://github.com/lobehub/lobe-editor',
},
socialLinks: [
{ href: 'https://github.com/lobehub/lobe-editor', icon: 'github', label: 'GitHub' },
],
},
};The package's only stable JS entry is
@lobehub/docs-kit/react-router-config; there is no root export fordefineDocsConfig. It is an identity function, so export a plain object. (lobe-ui imports it from./packages/docs-kit/src/configonly because it is the workspace.)
Restart lobedocs dev after editing docs.config.ts — config is cached per process.
All fields (multiple atomDirs, subType, homePage, publicDocs, navItems, giscus,
analytics, legacyRedirects) are in reference/config.md.
src/<Name>/index.mdx)Template:
---
title: Button
description: Button triggers an action. Supports variants, sizes, loading and icon slots.
category: General
order: -1
---
import Variants from './demos/Variant.tsx?demo';
import Basic from './demos/index.tsx?demo';
## Introduction
One or two paragraphs: what it is, when to use it, when to use something else.
## Basic Usage
<Demo of={Basic} title="Basic usage" layout="bare" />
## Variants
Explain the dimension first, then show it.
<Demo of={Variants} title="Variants" />
## API
<Api name="Button" />
Additionally, Button supports all props of antd's Button except `icon`.| Field | Required | Effect |
|---|---|---|
title | yes | H1, <title>, sidebar label. If PascalCase, the header shows import { Title } from '<packageName>' — match the export name |
description | yes | Subtitle, meta/OG description, search, llms.txt. One or two plain sentences, no markdown |
category | yes (component) | Sidebar group inside the section. Reuse existing names; General sorts first |
order | no | Number, lower first within category; unset sorts last, then by title |
status | no | stable | beta | experimental | deprecated |
since | no | Version string |
route | no | Override the URL; component pages must stay under /components/ |
Anything else (group, nav, apiHeader, dumi's hero) is ignored — remove it.
URL is derived from the folder: src/Button/index.mdx → /components/button,
src/base-ui/Select/index.mdx → /components/base-ui/select (each segment kebab-cased).
The page already renders title as the H1. Start body sections at ##; a stray # is
downgraded to H2. Every heading gets an anchor and appears in the outline and llms.txt, so use
short, stable, noun-style headings (## Variants, ## Controlled, ## API).
import Basic from './demos/index.tsx?demo';
<Demo of={Basic} title="Basic usage" description="Optional caption." layout="center" />| Prop | Default | Use |
|---|---|---|
of | — | Required. The ?demo import (without ?demo you get the raw component and it fails) |
title / description | — | Caption above the demo |
layout | 'default' | 'bare' no padding/frame (playgrounds, full-width); 'center' centered small elements |
isolated | false | Render in an iframe — for fixed/portal/global-CSS demos that would leak into the page |
editable | true | Set false if the demo uses dynamic import(), workers, or odd local deps |
height | — | Frame height, e.g. for isolated demos |
Demo file rules:
export default component; import the library by its package name
(import { Button } from '@lobehub/editor') so the shown source is copy-pasteable — the
alias maps it back to src/.Variant.tsx, Controlled.tsx), index.tsx
for the basic one.StoryBook + useControls from
@lobehub/ui/storybook with layout="bare".<Api name="Button" /> <!-- resolves via nearest index.ts barrel -->
<Api name="ChatItem" from=".." /> <!-- module path relative to this index.mdx -->Only static name and from are allowed (data is compiler-owned; migrationKey in old
lobe-ui pages is inert). Props are extracted from TypeScript, so the quality of the table is the
quality of your types:
export interface ButtonProps {
/**
* Adds a frosted-glass background.
* @default false
*/
glass?: boolean;
/** @deprecated Use `variant="filled"` instead. */
filled?: boolean;
}@default, @deprecated, @since.@default must match the runtime destructuring default, or the build fails.any / unknown props fail the build — type them._ are hidden; inherited React/HTML attributes collapse into a footnote.Demo and Api. Import anything else explicitly
(e.g. import { Alert } from '@lobehub/ui').::: callout syntax.```tsx | pure meta is
harmless but meaningless; plain ```tsx is preferred for new pages..md files can be imported as components: import Changelog from '../CHANGELOG.md'.docs/<path>.mdx (frontmatter title + description) and list it in
publicDocs: ['docs/<path>.mdx'] → served at /<path>. Guides get no sidebar entry; link to
them via themeConfig.navItems.docs/index.mdx needs frontmatter. Without homePage, the default home is built
from themeConfig.home (hero, features, install). With homePage: './docs/home/home.tsx',
that module's default export renders instead and receives
{ description: string; getStartedPathname: string }.docs/changelog.mdx importing ../CHANGELOG.md, or just a root
CHANGELOG.md (no frontmatter needed).- [ ] index.mdx exists at src/<Name>/index.mdx with title, description, category
- [ ] every <Demo of={X}> has a matching `import X from './demos/….tsx?demo'`
- [ ] demos default-export and import the package by name
- [ ] <Api name> matches an exported component; props typed with JSDoc
- [ ] dumi leftovers removed: <code src=…>, `group:`, `nav:`, `hero:`, `apiHeader:` frontmatter
- [ ] `lobedocs dev`, open the page, check demos + API table render
- [ ] `lobedocs build` passes (it runs all audits)When the build fails, the error lists the offending file and rule; see reference/validations.md for every rule and the fix.
docs.config.ts field, multi-package
atomDirs, sections/navigation, React Router overrides, tsconfig for typegenlobedocs build and why5c1ecb4
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.