SuperAPI AI Directory

using-docs-kit

Frontend & websites

View repository

Updated 10-16 06:23

About this skill

Using @lobehub/docs-kit

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/.

1. Repo layout

<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.md

Hard rules the compiler enforces:

  • Only files named index.mdx under an atomDirs root become component pages (index.md and README.md are ignored).
  • Demo files must live under src/**/demos/** — standalone /~demos/:id routes and isolated demos are globbed from that path only.
  • Other docs/**/*.mdx files are not discovered unless listed in publicDocs.

2. Install and scripts

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.

3. Minimal docs.config.ts

export 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 for defineDocsConfig. It is an identity function, so export a plain object. (lobe-ui imports it from ./packages/docs-kit/src/config only 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.

4. Writing a component page (src/<Name>/index.mdx)

Template:

---
title: Button
description: Button triggers an action. Supports variants, sizes, loading and icon slots.
category: General
order: -1
---

import Basic from './demos/index.tsx?demo';
import Variants from './demos/Variant.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`.

Frontmatter

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).

Headings

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).

Demos

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:

  • Exactly one 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/.
  • One idea per demo; name files after the idea (Variant.tsx, Controlled.tsx), index.tsx for the basic one.
  • Keep it self-contained: no fetching, no reliance on site state; mock data inline.
  • Interactive playgrounds (lobe-ui style) use StoryBook + useControls from @lobehub/ui/storybook with layout="bare".

API table

<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;
}
  • The JSDoc body is the description; supported tags: @default, @deprecated, @since.
  • @default must match the runtime destructuring default, or the build fails.
  • any / unknown props fail the build — type them.
  • Props starting with _ are hidden; inherited React/HTML attributes collapse into a footnote.

Other MDX content

  • Globals available without import: only Demo and Api. Import anything else explicitly (e.g. import { Alert } from '@lobehub/ui').
  • GFM is on (tables, task lists, strikethrough). No ::: callout syntax.
  • Code fences are highlighted only — never executed. dumi's ```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'.

5. Guides, home, changelog

  • Guide pages: add 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.
  • Home: 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 }.
  • Changelog: either docs/changelog.mdx importing ../CHANGELOG.md, or just a root CHANGELOG.md (no frontmatter needed).

6. Workflow for adding or migrating a page

- [ ] 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.

Additional resources