@mintlify/cli 4.0.1763 → 4.0.1765

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/__test__/migrate.test.ts +186 -0
  2. package/__test__/validateRules.test.ts +36 -0
  3. package/bin/cli.js +35 -0
  4. package/bin/migrate.js +54 -0
  5. package/bin/tsconfig.build.tsbuildinfo +1 -1
  6. package/bin/validate/files.js +16 -4
  7. package/bin/validate/mdx.js +1 -1
  8. package/migrate/index.md +56 -0
  9. package/migrate/sources/confluence.md +120 -0
  10. package/migrate/sources/docsify.md +128 -0
  11. package/migrate/sources/document360.md +117 -0
  12. package/migrate/sources/docus.md +136 -0
  13. package/migrate/sources/docusaurus.md +143 -0
  14. package/migrate/sources/fern.md +130 -0
  15. package/migrate/sources/fumadocs.md +141 -0
  16. package/migrate/sources/gitbook.md +120 -0
  17. package/migrate/sources/github-wiki.md +90 -0
  18. package/migrate/sources/jekyll.md +104 -0
  19. package/migrate/sources/mdbook.md +98 -0
  20. package/migrate/sources/mkdocs.md +113 -0
  21. package/migrate/sources/nextra.md +144 -0
  22. package/migrate/sources/notion.md +99 -0
  23. package/migrate/sources/nuxt.md +113 -0
  24. package/migrate/sources/pdf.md +99 -0
  25. package/migrate/sources/readme.md +118 -0
  26. package/migrate/sources/redocly.md +114 -0
  27. package/migrate/sources/starlight.md +136 -0
  28. package/migrate/sources/vitepress.md +143 -0
  29. package/migrate/sources/vuepress.md +153 -0
  30. package/migrate/topics/api.md +76 -0
  31. package/migrate/topics/changelog.md +47 -0
  32. package/migrate/topics/conversion.md +194 -0
  33. package/migrate/topics/discovery.md +93 -0
  34. package/migrate/topics/navigation.md +82 -0
  35. package/migrate/topics/verify.md +58 -0
  36. package/package.json +10 -10
  37. package/src/cli.tsx +47 -0
  38. package/src/migrate.ts +76 -0
  39. package/src/validate/files.ts +23 -3
  40. package/src/validate/mdx.ts +1 -1
@@ -0,0 +1,136 @@
1
+ # Docus
2
+
3
+ Nuxt layer for docs built on Nuxt Content (MDC Markdown in `content/`) and Nuxt UI (prose components). Generic Nuxt Content handling (`_payload.json`, `routeRules`, `/_ipx/` images): `mint migrate --from nuxt`. This guide covers the Docus repo layout and the Nuxt UI component syntax.
4
+
5
+ ## Detect
6
+
7
+ - `docus` in `package.json` dependencies; `nuxt.config.ts` with `extends: ['docus']`, or scripts running `nuxt dev --extends docus` with no config file.
8
+ - `content/` with numeric-prefixed names (`1.getting-started/2.installation.md`) and `.navigation.yml` files.
9
+ - `@nuxt-themes/docus` instead means the old Docus (Nuxt Content 2, `_dir.yml`, different components). Its syntax is not covered here: follow `mint migrate --from nuxt`, flag every unmapped component and report.
10
+ - A `docus` dependency wins over the generic Nuxt signals.
11
+
12
+ ## Get the source
13
+
14
+ ### From the repo
15
+
16
+ Reference: https://docus.dev/en/getting-started/project-structure
17
+
18
+ - Root is the folder whose `package.json` depends on `docus` (often `docs/` in a monorepo).
19
+ - Pages: `content/**/*.md`. `content/index.md` is the landing page.
20
+ - `content/docs/` present: documentation lives there and is served under `/docs/...`; other files beside it are separate site pages: ask the user whether to migrate them.
21
+ - i18n: one folder per locale code (`content/en/`, `content/fr/`), each with its own `index.md`.
22
+ - Read `app.config.ts` (or `app/app.config.ts`), `nuxt.config.ts`, `content.config.ts` if present (extra collections such as a blog or changelog: see `mint migrate --topic changelog`), and `app/components/content/*.vue` (custom MDC components).
23
+ - `app/pages/*.vue` are Vue routes, not content: list them and report.
24
+
25
+ ### From an export
26
+
27
+ None; the site is built from the repo.
28
+
29
+ ### From the live site
30
+
31
+ `_payload.json` extraction: (`mint migrate --from nuxt`, From the live site).
32
+
33
+ ## Config → docs.json
34
+
35
+ Reference: https://docus.dev/en/concepts/configuration
36
+
37
+ | Docus | docs.json |
38
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
39
+ | `seo.title`, else `site.name` in `nuxt.config.ts`, else `package.json` `name` | `name` |
40
+ | `seo.description`, else `package.json` `description` | `description` |
41
+ | `header.logo.light` / `header.logo.dark` | `logo.light` / `logo.dark` (by key; Docus file names are often inverted) |
42
+ | `header.logo.display: 'wordmark'` | `logo` from `header.logo.wordmark.light` / `.dark` |
43
+ | `header.logo.favicon`, else `public/favicon.ico` | `favicon` |
44
+ | `ui.colors.primary` (Tailwind color name; unset means the Nuxt UI default) | `colors.primary`: read `--ui-primary` from the live site's CSS and resolve it to hex |
45
+ | `docus.colorMode: 'light'` / `'dark'` | `appearance.default` + `appearance.strict: true` |
46
+ | `socials` (Simple Icons key → URL, shown in the footer) | `footer.socials` for keys Mintlify supports; others: drop and report |
47
+ | `github.url` (or the git remote when `github` is unset) | `navbar.links` entry with `type: "github"`, only if the header showed it |
48
+ | `navigation.sub: 'header'` | `navigation.tabs`, one per top-level folder |
49
+ | `navigation.sub: 'aside'` | `navigation.anchors`, one per top-level folder |
50
+ | `nuxt.config.ts` `i18n.locales`, `defaultLocale` | `navigation.languages`, `default: true` on the default |
51
+ | `nuxt.config.ts` `routeRules` redirects | `redirects` (see `mint migrate --from nuxt`) |
52
+ | `github.branch` / `rootDir` (edit and issue links), `toc.title`, `toc.bottom`, `search`, `seo.titleTemplate`, `seo.schema`, `docus.locale`, `docus.shortcuts`, other `ui.*`, `app/app.css` theme | drop and report |
53
+ | `assistant`, `mcp`, `llms` settings | drop and report |
54
+
55
+ ## Navigation
56
+
57
+ References: https://content.nuxt.com/docs/collections/types#ordering-files, https://content.nuxt.com/docs/utils/query-collection-navigation
58
+
59
+ - The sidebar is the `content/` tree (or `content/docs/`, or `content/<locale>/`). Each folder → a group; files and subfolders → its pages and nested groups.
60
+ - Order: siblings sort alphabetically by their full prefixed name, so `10.faq` comes before `2.setup` unless padded (`02.`). Reproduce that exact order; confirm against the live sidebar.
61
+ - Group label and icon: the folder's `.navigation.yml` `title`, and `icon` (top-level or under `navigation:`). No `.navigation.yml`: copy the label the live sidebar shows.
62
+ - Folder `index.md` → first page of its group.
63
+ - Page frontmatter `navigation: false`: not in the sidebar (`mint migrate --topic navigation`, Structure rules). `navigation.title` → `sidebarTitle`; `navigation.icon` → `icon`.
64
+ - Icons are Iconify names (`mint migrate --topic conversion`, Icons).
65
+ - With `navigation.sub` set, each top-level folder becomes a tab or anchor holding that folder's groups.
66
+
67
+ ## Content conversion
68
+
69
+ Syntax references: https://content.nuxt.com/docs/files/markdown, https://ui.nuxt.com/docs/typography
70
+
71
+ MDC structure:
72
+
73
+ - Block: `::name{key="value" flag}` ... `::`. Nested blocks add a colon (`:::tabs-item` inside `::tabs`), and each closer has its opener's colon count.
74
+ - Props: inline `{...}`, or a YAML block between `---` lines right after the opener. `:prop='json'` binds a value. Props are data: never emit them as text.
75
+ - Slots: `#name` lines inside a block (`#title`, `#description`, `#default`, `#code`).
76
+ - Inline: `:name{props}`. Spans `[text]{.class #id style="..."}` → `text`. Attributes on inline code (`` `x`{lang="ts"} ``) → `` `x` ``.
77
+
78
+ `::note`, `::tip`, `::warning`: `mint migrate --topic conversion`, Admonitions.
79
+
80
+ | Docus / Nuxt UI | Mintlify |
81
+ | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
82
+ | `::caution` | `<Danger>` |
83
+ | `::callout{color="info"}` / `"warning"` / `"error"` / `"success"` | `<Info>` / `<Warning>` / `<Danger>` / `<Check>` |
84
+ | `::callout` with `neutral`, `primary`, `secondary` or no color | `<Callout icon="...">` with a Font Awesome icon, else `<Note>` |
85
+ | callout `to` / `target` | add the link to the callout text; report |
86
+ | `::tabs` + `:::tabs-item{label icon}` | `<Tabs>` + `<Tab title icon>`; drop `sync`, `hash`, `defaultValue` |
87
+ | `::code-group` of `[label]` fences | `<CodeGroup>`, label → fence title; drop `sync` |
88
+ | `::code-tree{default-value}` | `<CodeGroup>`, each fence titled with its path; report the tree view |
89
+ | `::code-collapse` around a fence | the fence with `expandable` |
90
+ | `::code-preview` (default slot + `#code`) | the rendered content, then the `#code` fence; report |
91
+ | `::steps{level="N"}` (default level 3) | `<Steps>`; each heading of that level → `<Step title>`, content up to the next one as body |
92
+ | `::card-group` | `<Columns cols={2}>` |
93
+ | `::card{title icon to target color}` | `<Card title icon href>`; drop `color`, `target` |
94
+ | `::accordion` + `:::accordion-item{label icon}` | `<AccordionGroup>` + `<Accordion title icon>` |
95
+ | `::collapsible{name}` | `<Accordion title>` with the trigger label shown on the live site |
96
+ | `::field-group` + `::field{name type required description}` | `<ResponseField name type required>` per field, `description` or slot as body; drop the group wrapper |
97
+ | `::badge` | `<Badge>` |
98
+ | `:icon{name}` | `<Icon icon>` (`mint migrate --topic conversion`, Icons) |
99
+ | `:kbd{value}` | `<kbd>value</kbd>` |
100
+ | `:video{src autoplay controls loop}` | `<video src controls autoPlay loop>` |
101
+ | `u-page-*` and other `u-*` Nuxt UI components (landing page) | headings, paragraphs and `<Card>`s from their props and slots; report |
102
+ | custom `app/components/content/*.vue` | `mint migrate --topic conversion`, Components |
103
+
104
+ Code fences:
105
+
106
+ | Docus | Mintlify |
107
+ | ---------------------------------------- | -------------------------------------------------------------------- |
108
+ | ` ```ts [nuxt.config.ts] ` | ` ```ts nuxt.config.ts ` (`title="..."` if the label has spaces) |
109
+ | ` ```ts [file.ts] {2,4-5} ` | ` ```ts file.ts highlight={2,4-5} ` |
110
+ | ` ```diff [file.ts] ` with `+`/`-` lines | the file's language; strip prefixes, add `[!code ++]` / `[!code --]` |
111
+
112
+ Frontmatter (https://docus.dev/en/concepts/edition):
113
+
114
+ - `title` → `title`. If missing, Nuxt Content took the first `# H1`: move it into `title`.
115
+ - `description` renders under the title: keep it.
116
+ - `navigation` → see Navigation. `seo.title` / `seo.description` override meta only: drop and report.
117
+ - `layout`, `links`, `sitemap`, other keys → drop and report.
118
+ - `content/index.md` (landing) → `mode: "custom"`; leave it out of the sidebar groups.
119
+
120
+ ## Assets
121
+
122
+ - `public/` is served at the site root; Docus pages reference it root-absolute (`mint migrate --topic conversion`, Images and files).
123
+ - Images under `app/assets/` or referenced from Vue components: same handling.
124
+ - Logo and favicon paths in `app.config.ts` are `public/` paths.
125
+
126
+ ## URLs and redirects
127
+
128
+ - Path = file path under `content/` minus extension, numeric `N.` prefixes stripped from every segment, `index` dropped: `content/1.guide/2.installation.md` → `/guide/installation`. Rename files without prefixes to keep those paths.
129
+ - With `content/docs/`, every doc path starts with `/docs/`: keep a `docs/` folder in Mintlify.
130
+ - i18n forces a prefix on every locale, the default included (`/en/guide/...`), and `/` redirects to the default locale. Keep `en/`, `fr/` folders. Regional codes appear lowercase in URLs (`zh-TW` → `/zh-tw/`): name the folder in lowercase. Ask the user how `/` should resolve.
131
+ - A locale listed in `nuxt.config.ts` without a `content/<code>/` folder was never published: skip it.
132
+ - `nuxt.config.ts` `routeRules` redirects: see `mint migrate --from nuxt`.
133
+
134
+ ## Known gaps
135
+
136
+ Report each: Docus AI assistant, MCP server and `llms.txt` settings; Studio; `code-tree` file browser and `code-preview` live rendering; callout links and colors; card colors; Iconify icons with no Font Awesome match; landing-page `u-page-*` layout; custom Vue components and `app/pages/*.vue` routes; `navigation.sub` behavior beyond tabs or anchors; `toc.bottom` links; theme CSS and `ui.*` overrides; old Docus (`@nuxt-themes/docus`) components.
@@ -0,0 +1,143 @@
1
+ # Docusaurus
2
+
3
+ React static site generator. Content is MD/MDX under the docs plugin's `path`; navigation is executable JS/TS (`sidebars.js`) plus `_category_.json`/`.yml` files and doc front matter.
4
+
5
+ ## Detect
6
+
7
+ - `docusaurus.config.{js,mjs,ts}` at the site root, `@docusaurus/core` in `package.json`.
8
+ - `sidebars.{js,ts}`, `_category_.json`/`_category_.yml` in content folders, `static/`, `versioned_docs/`, `versions.json`, `i18n/`.
9
+ - Live site: `<meta name="generator" content="Docusaurus ...">`, `__docusaurus` in the HTML, `/assets/js/runtime~main.*.js`.
10
+ - Config file wins over everything else. Read the `@docusaurus/core` major from `package.json`: v2 (MDX 1) and v3 (MDX 3) need different content fixes (below).
11
+
12
+ ## Get the source
13
+
14
+ Mintlify's guide for this platform: https://www.mintlify.com/docs/migration/docusaurus.md
15
+
16
+ ### From the repo
17
+
18
+ - Read `docusaurus.config.*` first: every `@docusaurus/plugin-content-docs` instance (preset `docs` or `plugins` with an `id`) has its own `path` (default `docs`), `routeBasePath`, `sidebarPath`, `include`/`exclude`. Each instance is a separate docs tree.
19
+ - Also inventory `src/pages/**/*.md(x)` (standalone pages) and `blog/` if the user wants them; `src/pages/*.tsx` React pages have no source to convert: report them.
20
+ - Versions: `versioned_docs/version-<name>/` with `versioned_sidebars/version-<name>-sidebars.json`; order in `versions.json` (newest first). `docs/` is the `current` version.
21
+ - Locales: `i18n/<locale>/docusaurus-plugin-content-docs/current/` (and `.../version-<name>/` for versions), sidebar/category label translations in `i18n/<locale>/docusaurus-plugin-content-docs/current.json`.
22
+ - Files prefixed with `_` are partials (not pages). `draft: true` docs are not published: exclude them.
23
+
24
+ ### From an export
25
+
26
+ None; the site is built from the repo.
27
+
28
+ ### From the live site
29
+
30
+ Scrape with `npx -p @mintlify/scraping@latest -p puppeteer mintlify-scrape section <url>` (add `--filter=/docs` for a `routeBasePath`), then fix port artifacts E (`prism-code` fences) and F (admonition leaked into `description`) (`mint migrate --topic conversion`, Port artifacts).
31
+
32
+ ## Config → docs.json
33
+
34
+ | Docusaurus | docs.json |
35
+ | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
36
+ | `title` | `name` |
37
+ | `tagline` | `description` |
38
+ | `favicon` (path in `static/`) | `favicon` |
39
+ | `themeConfig.navbar.logo` `src` / `srcDark` / `href` | `logo.light` / `logo.dark` / `logo.href` |
40
+ | `themeConfig.navbar.items` of type `doc`, `docSidebar` | `navigation.tabs` (one per sidebar) |
41
+ | `themeConfig.navbar.items` with `href` (external) | `navbar.links` (GitHub link: `type: "github"`) |
42
+ | `themeConfig.navbar.items` `docsVersionDropdown`, `localeDropdown` | drop: replaced by `navigation.versions` / `navigation.languages` switchers |
43
+ | `themeConfig.navbar.items` `search`, `html`, custom types | drop and report |
44
+ | `themeConfig.footer.links` (columns) | `footer.links` (`title` → `header`, `items[].to`/`href` → `href`) |
45
+ | `themeConfig.footer.copyright`, `footer.logo`, `footer.style` | drop and report |
46
+ | `themeConfig.colorMode.defaultMode` / `disableSwitch` | `appearance.default` / `appearance.strict` |
47
+ | `themeConfig.prism.theme` / `darkTheme` | `styling.codeblocks` only if a matching Shiki theme exists; else drop and report |
48
+ | `themeConfig.announcementBar` `content` / `isCloseable` | `banner.content` (HTML → Markdown links) / `banner.dismissible`; colors drop |
49
+ | `themeConfig.metadata`, `themeConfig.image` | `seo.metatags` (`image` → `"og:image"`) |
50
+ | `themeConfig.algolia` | drop and report |
51
+ | `i18n.locales` / `defaultLocale` | `navigation.languages` (use a supported code) |
52
+ | preset `gtag.trackingID` | `integrations.ga4.measurementId` |
53
+ | preset `googleTagManager.containerId` | `integrations.gtm.tagId` |
54
+ | `@docusaurus/plugin-client-redirects` `redirects` | `redirects` (see URLs) |
55
+ | `@docusaurus/theme-mermaid`, `remark-math` + `rehype-katex` | drop (native in Mintlify); keep the fences and `$` math |
56
+ | `url`, `baseUrl`, `trailingSlash` | drop; use them to compute old URLs |
57
+ | `docs.editUrl`, `showLastUpdateTime`, `showLastUpdateAuthor`, `breadcrumbs` | drop and report |
58
+ | `theme.customCss`, swizzled `src/theme/*` | drop and report |
59
+ | OpenAPI plugins (`docusaurus-plugin-openapi-docs`, `redocusaurus`) | spec file; see `mint migrate --topic api` |
60
+
61
+ ## Navigation
62
+
63
+ - Resolve the sidebar, do not parse it as text: run `node -e "console.log(JSON.stringify(require('./sidebars.js'),null,2))"` (for TS or ESM, import it with `npx tsx`). If `sidebarPath` is unset, the whole sidebar is autogenerated from the docs folder.
64
+ - One sidebar object key = one tab (or one group if there is only one sidebar). Keep item order, labels and nesting.
65
+ - Item mapping:
66
+ - doc id string or `{type: 'doc', id, label}` → page path (`label` differing from the H1 → `sidebarTitle`).
67
+ - `{type: 'category', label, items}` → nested group with `group: label`.
68
+ - category `link: {type: 'doc', id}` → that doc is the group `root`.
69
+ - category `link: {type: 'generated-index', title, description, slug}` → create an index page from those fields (cards for the children) and make it the `root`; its old URL is `/<routeBasePath>/category/<category name>` (slugified) unless `slug` is set.
70
+ - `{type: 'link', href, label}` → a page whose frontmatter is `title: label` + `url: href`, listed at that position; `{type: 'html'}` → drop and report; `{type: 'ref'}` → page path.
71
+ - `collapsed: false` on a nested category → `expanded: true`.
72
+ - Doc ids: default id is the file path without extension and number prefixes; front matter `id` replaces only the last segment. Map ids to files before mapping the sidebar.
73
+ - `{type: 'autogenerated', dirName}`: expand it the way Docusaurus does. Order within a folder: `sidebar_position` (docs) and `_category_` `position` (folders) ascending, then alphabetical by file/folder name. Number prefixes (`01-intro.md`) order items and are stripped from ids, labels and URLs. Folder label: `_category_` `label`, else folder name. A folder's `index.md`, `README.md` or `<folder>/<folder>.md` is the category's linked doc (group `root`), unless `_category_` sets `link` (`mint migrate --topic conversion`, Files).
74
+ - Labels: `sidebar_label` → `sidebarTitle`. `_category_` `className`, `customProps`, `collapsible` → drop.
75
+ - Cross-check the result against the rendered sidebar on the live site; custom `sidebarItemsGenerator` functions change all of the above.
76
+ - Versions: one `navigation.versions` entry per kept version, built from `versioned_sidebars/`; make the `lastVersion` (default: first in `versions.json`) the default. Keep version content in per-version folders.
77
+ - Doc front matter `displayed_sidebar`, `pagination_*` → drop.
78
+
79
+ ## Content conversion
80
+
81
+ Admonitions: (`mint migrate --topic conversion`, Admonitions). Docusaurus-specific mapping:
82
+
83
+ | Docusaurus | Mintlify |
84
+ | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
85
+ | `:::warning` | `<Warning>` (v2: rendered red, use `<Danger>` if the text warns of damage) |
86
+ | Admonition title (v3 `:::note[Title]`, v2 `:::note Title`) | (`mint migrate --topic conversion`, Components) |
87
+ | `<Admonition type="...">` from `@theme/Admonition` | same mapping as the directive |
88
+ | `<Tabs>` + `<TabItem value label default>` | `<Tabs>` + `<Tab title={label}>` (no `label` → `value`); `default`/`defaultValue` → `defaultTabIndex` |
89
+ | `groupId`, `queryString`, `lazy`, `values={[...]}` | drop (titles in `values` become `Tab` titles) |
90
+ | Tabs whose every item is one code block | `<CodeGroup>` with the label as the fence title |
91
+ | ` ```js title="a.js" ` | ` ```js a.js ` or keep `title="a.js"` |
92
+ | ` ```js {1,4-6} ` | `highlight={1,4-6}` |
93
+ | `// highlight-next-line`, `// highlight-start` / `// highlight-end` | remove the comment lines; put the resulting line numbers in `highlight={...}` |
94
+ | `showLineNumbers` (`=N` start offset) | `lines` (offset drops) |
95
+ | ` ```bash npm2yarn ` | (`mint migrate --topic conversion`, Package-manager tabs) |
96
+ | ` ```jsx live ` (theme-live-codeblock) | static code block; report |
97
+ | `<CodeBlock language title>` from `@theme/CodeBlock` | fenced block |
98
+ | `import X from './_x.mdx'` + `<X />` (partial) | (`mint migrate --topic conversion`, Reusable content) |
99
+ | `import Code from './file.js' with {type: 'text'}` | (`mint migrate --topic conversion`, Code imports) |
100
+ | `<details><summary>T</summary>` | `<Accordion title="T">` |
101
+ | `<DocCardList />` | `<Card>` per child page in a `<Columns cols={2}>` |
102
+ | `<TOCInline toc={toc} />` | drop and report |
103
+ | `@site/src/components/*` | (`mint migrate --topic conversion`, Components) |
104
+ | `useBaseUrl(...)`, `useDocusaurusContext`, `@docusaurus/*` imports | resolve to a literal value; drop the import |
105
+ | `@theme/*` imports | delete after converting the component |
106
+ | `<!-- truncate -->` / `{/* truncate */}` (blog) | delete |
107
+
108
+ Heading ids: v3 `## Title {/* #id */}` and v2/`mdx1Compat` `## Title {#id}` (`mint migrate --topic conversion`, Heading IDs).
109
+
110
+ Front matter: `id` → drop (used for URLs, see below); `slug` → drop (used for URLs); `title`, `keywords` keep; `sidebar_label` → `sidebarTitle`; `unlisted: true` → `hidden: true`; `image` → `"og:image"`; `hide_title`, `hide_table_of_contents`, `toc_*_heading_level`, `sidebar_position`, `sidebar_class_name`, `sidebar_custom_props`, `sidebar_key`, `custom_edit_url`, `last_update`, `parse_number_prefixes`, `tags` → drop. `description` is meta-only and defaults to the first line of content (`mint migrate --topic conversion`, Frontmatter).
111
+
112
+ MDX version: v2 sources are MDX 1 and often contain `<!-- -->` comments, unescaped `{`/`<`, string `style` attributes (`mint migrate --topic conversion`, MDX safety). v3 with `markdown.format: 'detect'` treats `.md` as CommonMark.
113
+
114
+ ## Assets
115
+
116
+ - `static/` and every `staticDirectories` entry are served at the site root: `static/img/a.png` → `/img/a.png` (`mint migrate --topic conversion`, Images and files).
117
+ - `@site/static/img/a.png` in imports or `require()` → `/img/a.png`.
118
+ - Co-located images (`./assets/a.png`, `require('./a.png')`, `import img from './a.png'`) → move under a root folder and rewrite to root-relative paths.
119
+ - `pathname:///img/a.png` → `/img/a.png`.
120
+ - GitHub-style themed images (`#gh-light-mode-only` / `#gh-dark-mode-only`) and `@theme/ThemedImage` → two `<img>` tags with `className="block dark:hidden"` / `"hidden dark:block"`.
121
+ - `@docusaurus/plugin-ideal-image` `<Image img={require(...)}/>` → `<img>`.
122
+
123
+ ## URLs and redirects
124
+
125
+ - Doc URL = `baseUrl` + `routeBasePath` (default `docs`; `/` means docs-only) + version path + slug. Locale prefix `/<locale>/` comes before everything for non-default locales.
126
+ - Slug: front matter `slug` (absolute `/x` from `routeBasePath`, relative `x` from the doc's folder); else the doc id path with number prefixes removed; `index`, `README` and `<folder>/<folder>` files resolve to the folder URL.
127
+ - Versions: `lastVersion` serves at `/<routeBasePath>/`, `current` at `/<routeBasePath>/next/` (unless `lastVersion: 'current'`), others at `/<routeBasePath>/<version>/`; `versions.<name>.path` overrides.
128
+ - `trailingSlash: true` → URLs end in `/`; `false` → files emitted as `/docs/page.html`, so hosts may also serve the `.html` form.
129
+ - Emit redirects (`mint migrate --topic navigation`, Redirects) for: the `routeBasePath` prefix if you move docs to root, every slug/id-based URL that differs from the new file path, `/category/<slug>` generated-index pages, version and locale prefixes, and every existing `plugin-client-redirects` entry (`from` array → one entry each, `to` → `destination`). `createRedirects` functions and `fromExtensions`/`toExtensions`: expand to exact entries from the sitemap.
130
+ - Tags pages (`/<routeBasePath>/tags/...`) have no target: redirect to the closest page or report.
131
+
132
+ ## Known gaps
133
+
134
+ Report each that the site uses:
135
+
136
+ - Swizzled theme components, `src/theme/*`, custom CSS (Infima classes do not exist in Mintlify).
137
+ - React pages in `src/pages/*.tsx`, interactive components without a static equivalent, `react-live` blocks.
138
+ - Doc tags and tag index pages, `<TOCInline>`, per-page TOC heading levels.
139
+ - Edit URLs, last-updated author/time, breadcrumbs toggle, pagination overrides.
140
+ - Tab `groupId` persistence and `queryString` deep links.
141
+ - Docusaurus blog (author pages, tag/archive pages, RSS): see `mint migrate --topic changelog` if it is a changelog.
142
+ - Algolia DocSearch config and any search plugin.
143
+ - Docs plugin instances beyond what tabs/products can hold, `onlyIncludeVersions` subsets.
@@ -0,0 +1,130 @@
1
+ # Fern
2
+
3
+ ## Detect
4
+
5
+ - `fern/docs.yml` next to `fern/fern.config.json` (also nested, for example `docs/fern/`). `fern.config.json` without `docs.yml` is an SDK-only project; the docs live elsewhere.
6
+ - API definitions in the same folder: `generators.yml` with `api.specs` (OpenAPI, AsyncAPI), `fern/apis/<name>/` for several APIs, or a Fern Definition (`api.yml` plus YAML service and type files).
7
+ - A stale `docs.yml` can outlive a move off Fern. Confirm the live site: `curl -sI https://<docs-domain>/ | grep -i x-fern`.
8
+ - Only the docs move. Do not delete or edit `generators.yml`, the definition or `fern.config.json`; SDK generation uses them.
9
+
10
+ ## Get the source
11
+
12
+ Mintlify's guide for this platform: https://www.mintlify.com/docs/migration/fern.md
13
+
14
+ ### From the repo
15
+
16
+ - Read `docs.yml`, then every file it references (product and version YAML, redirect files, `css`, `js`). Paths in a Fern YAML file are relative to that file.
17
+ - Pages: `.md`/`.mdx` files referenced by a `path` or found by a `folder` entry. Unreferenced files are not published.
18
+ - Snippets live in a `snippets/` folder; changelog entries in a `changelog/` folder (reserved name).
19
+
20
+ ### From an export
21
+
22
+ Not covered yet. Use the repo.
23
+
24
+ ### From the live site
25
+
26
+ Clean Markdown at `<page-url>.md`; page list at `/llms.txt`.
27
+
28
+ Reference: https://buildwithfern.com/learn/docs/getting-started/project-structure
29
+
30
+ ## Config → docs.json
31
+
32
+ | docs.yml | docs.json |
33
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
34
+ | `title` | `name` |
35
+ | `logo.light` / `logo.dark` / `logo.href` | `logo.light` / `logo.dark` / `logo.href` |
36
+ | `favicon` | `favicon` |
37
+ | `colors.accent-primary` (string or `{ light, dark }`) | `colors.primary` (+ `colors.light` / `colors.dark`) |
38
+ | `colors.background` | `background.color` |
39
+ | `typography.bodyFont` / `headingsFont` | `fonts.body` / `fonts.heading` |
40
+ | `navbar-links` `type: filled` | `navbar.primary` |
41
+ | `navbar-links` `type: github` | `navbar.links` (`type: github`) |
42
+ | `navbar-links` `type: minimal` / `outlined` (`url` is an older name for `href`) | `navbar.links` |
43
+ | `navbar-links` `type: dropdown` | flatten into `navbar.links`; report |
44
+ | `footer-links` | `footer.socials` (`hackernews` → `hacker-news`) |
45
+ | `announcement.message` | `banner.content` |
46
+ | `analytics.ga4.measurement-id`, `analytics.gtm.container-id`, `analytics.posthog.api-key` | `integrations.ga4.measurementId`, `integrations.gtm.tagId`, `integrations.posthog.apiKey` |
47
+ | `metadata.og:*`, `metadata.twitter:*` | `seo.metatags` |
48
+ | `settings.search-text` | `search.prompt` |
49
+ | `settings.http-snippets`, `default-language` | `api.examples.languages` |
50
+ | `css`, `js` | (`mint migrate --topic navigation`, Chrome) |
51
+ | `redirects` | URLs below |
52
+ | `instances[].url`, `custom-domain` | none; host and path are part of every old URL |
53
+ | `instances[].edit-this-page`, other `colors.*`, `layout.*`, `theme.*`, `settings.*`, `global-theme`, `page-actions`, `background-image`, `header` / `footer` components, `ai-search`, `ai-chat`, `landing-page` | drop and report |
54
+
55
+ Reference: https://buildwithfern.com/learn/docs/configuration/site-level-settings
56
+
57
+ ## Navigation
58
+
59
+ `docs.yml` `navigation` is the sidebar; folders on disk do not define it. References: https://buildwithfern.com/learn/docs/configuration/navigation, `/tabs`, `/versions`, `/products` under the same path.
60
+
61
+ - `tabs:` (key → `display-name`, `icon`, `slug`, `skip-slug`, `href`, `changelog`) with `navigation: - tab: <key>` + `layout:` → tabs; an `href` tab → tab `href`. Tab `variants`: keep the default; report.
62
+ - `section` + `contents` → group; nested sections → nested groups; section `path` → `root`; `collapsed: true` → `expanded: false`; `collapsed: open-by-default` → `expanded: true`.
63
+ - `page: Label` + `path` → page; `Label` (or frontmatter `sidebar-title`) → `sidebarTitle` when it differs from `title`.
64
+ - `folder: ./dir` (+ `title`) → group of that folder's files: `index` → `root`; frontmatter `position` (numeric) first, then alphabetical; subfolders → nested groups.
65
+ - `link` + `href` → `navigation.global.anchors`.
66
+ - `api: Name` (+ `api-name`) → a group with that API's spec.
67
+ - `changelog: ./changelog` → the changelog page at that position.
68
+ - `hidden: true` → hidden page or group.
69
+ - `availability` (`beta`, `pre-release`, `in-development`, `deprecated`) → `tag`, or `deprecated`.
70
+ - `products:` (`display-name`, `path`, `icon`, `subtitle`, `href`) → `navigation.products` (`subtitle` → `description`).
71
+ - `versions:` (`display-name`, `path`, `availability`) → `navigation.versions`; the first is the default.
72
+
73
+ ## Content conversion
74
+
75
+ Fern and Mintlify component names overlap but props differ. Reference: https://buildwithfern.com/learn/docs/writing-content/components/overview
76
+
77
+ | Fern | Mintlify |
78
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
79
+ | `<Note>`, `<Tip>`, `<Info>`, `<Warning>`, `<Check>` | same |
80
+ | `<Success>` / `<Error>` / `<Launch>` / `<Callout intent>` | `<Check>` / `<Danger>` / `<Info>` / the matching callout |
81
+ | `<TabGroup>`, `<Tab language>` | `<Tabs>`, `<Tab>` |
82
+ | `<CodeBlocks>` | `<CodeGroup>` |
83
+ | `<CodeBlock title>` around a fence | the fence with that title |
84
+ | fence `filename=`, `wordWrap`, `{1,3-4}` | fence title, `wrap`, `highlight={1,3-4}` |
85
+ | `<Code src>` | (`mint migrate --topic conversion`, Code imports) |
86
+ | `<CardGroup>` / `<Card>` | `<Columns>` / `<Card>` |
87
+ | `<ParamField path="name">` (Fern's `path` is the field name) | `<ParamField>` with `query`, `body`, `header` or `path` by context |
88
+ | `<Files>` / `<Folder>` / `<File>` | `<Tree>` / `<Tree.Folder>` / `<Tree.File>` |
89
+ | `<Badge intent>` | `<Badge color>` |
90
+ | `<Aside>` | `<Panel>` |
91
+ | `<Indent>` | unwrap; nested fields → `<Expandable>` |
92
+ | `<Button href>`, `<Download src>` | a link or `<Card>`, a link to the file |
93
+ | `<Versions>` / `<Version title>` | `<Tabs>` / `<Tab>` |
94
+ | `<If products versions roles>` | the content for this page's product or version; report role-gated text |
95
+ | `<EndpointRequestSnippet>`, `<EndpointResponseSnippet>`, `<EndpointSchemaSnippet>`, `<WebhookPayloadSnippet>`, `<Schema>`, `<RunnableEndpoint>` | link to the endpoint page, or `<RequestExample>` / `<ResponseExample>` with static fences; report |
96
+ | `<Markdown src="/snippets/x.mdx" k="v" />`; `{{k}}` inside the snippet | (`mint migrate --topic conversion`, Reusable content); `{{k}}` → `{k}` |
97
+ | custom React components | (`mint migrate --topic conversion`, Reusable content) |
98
+ | `## Title [#slug]` | (`mint migrate --topic conversion`, Heading IDs) |
99
+ | changelog files named `YYYY-MM-DD`, `MM-DD-YYYY` or `MM-DD-YY`; `overview.mdx`; frontmatter `tags`; `<ChangelogTags>` | see `mint migrate --topic changelog`; the file name is the date; drop `<ChangelogTags>` |
100
+ | frontmatter `sidebar-title`, `subtitle` | `sidebarTitle`, `description` (if none) |
101
+ | frontmatter `layout: reference` / `page` / `custom` | `mode: "wide"` / `"center"` / `"custom"` |
102
+ | frontmatter `hide-nav-links` / `last-updated` / `availability: deprecated` | `hideFooterPagination` / `lastUpdatedDate` / `deprecated` |
103
+ | frontmatter `slug`, `canonical-url` | URLs below |
104
+ | frontmatter `hide-toc`, `max-toc-depth`, `hide-feedback`, `hide-page-actions`, `edit-this-page-url`, `image`, `logo`, `headline`, `nofollow`, `jsonld*`, `search-metadata`, `position`, `layout: guide`/`overview` | drop |
105
+
106
+ ## Assets
107
+
108
+ - Copy asset folders referenced from pages and `docs.yml` (logo, favicon, fonts, icons) at their relative paths.
109
+ - OpenAPI/AsyncAPI specs from `generators.yml` `api.specs`: use them in place; download remote ones.
110
+ - Fern Definition: export with `fern export [--api <name>] <file>.json`; report that it must be re-exported when the definition changes.
111
+ - Fern `overlays` are OpenAPI Overlays. Fern `overrides` are Fern's own deep-merge format; `fern api enrich` merges their `x-fern-examples` into the spec; SDK-only `x-fern-*` keys can be ignored (`mint migrate --topic api`).
112
+
113
+ Reference: https://buildwithfern.com/learn/api-definitions/overview/project-structure
114
+
115
+ ## URLs and redirects
116
+
117
+ - URLs come from `docs.yml`, not file paths (https://buildwithfern.com/learn/docs/seo/configuring-slugs). Each level contributes its `slug` or its kebab-cased display name: product, version, tab, section, folder, page. `skip-slug: true` drops a level. A frontmatter `slug` replaces everything below the product/version prefix. The first version has no prefix.
118
+ - Compute each old URL with these rules and check it against `sitemap.xml`.
119
+ - Changelog entries were served at `<changelog-path>/<YYYY>/<M>/<D>` (no zero padding).
120
+ - Endpoint pages sat under the `api` entry's slug; to keep them, see `mint migrate --topic api`.
121
+ - `docs.yml` `redirects` (`source`, `destination`, `permanent`), including regex segments (`:slug(.*)`) and sources with more than one wildcard: (`mint migrate --topic navigation`, Redirects).
122
+
123
+ ## Known gaps
124
+
125
+ - Fern Definition content missing from the OpenAPI export; WebSocket, gRPC and OpenRPC references.
126
+ - SDK snippets from `generators.yml`, API Explorer behavior, audiences.
127
+ - Role, feature-flag and `viewers` gating; authentication.
128
+ - Tab variants, `landing-page`, custom header and footer components, global themes, Ask Fern.
129
+ - Same-day changelog entries Fern merged into one URL; changelog RSS URLs.
130
+ - Multiple `instances` (one Mintlify site per domain).
@@ -0,0 +1,141 @@
1
+ # Fumadocs
2
+
3
+ Docs built with Fumadocs (`fumadocs-core`, `fumadocs-ui`, `fumadocs-mdx`) on Next.js, React Router, TanStack Start, Waku or Astro. Reference: https://fumadocs.dev/docs/page-conventions and https://fumadocs.dev/docs/markdown.
4
+
5
+ ## Detect
6
+
7
+ - `package.json` has `fumadocs-core`, `fumadocs-ui` or `fumadocs-mdx`.
8
+ - `source.config.ts`, or `defineDocs` from `fumadocs-mdx/macro` in `lib/source.ts`, plus a `loader({ baseUrl, source })` call.
9
+ - `meta.json` files inside the content folder (default `content/docs/`).
10
+ - Live site: Tailwind classes prefixed `fd-` (`text-fd-primary`, `fd-steps`) and Next.js `/_next/` assets when hosted on Next.
11
+
12
+ The dependency wins. `meta.json` alone is not proof.
13
+
14
+ ## Get the source
15
+
16
+ ### From the repo
17
+
18
+ Content folder = `dir` in `defineDocs(...)`. Read alongside it:
19
+
20
+ - `lib/source.ts`: `baseUrl`, the `icon()` handler, `i18n`, loader `plugins` (they can rewrite slugs or the tree).
21
+ - `lib/layout.shared.tsx` (older: `app/layout.config.tsx`): `nav.title`, `links`, `githubUrl`.
22
+ - `components/mdx.tsx` (older: `mdx-components.tsx`): components usable in MDX without an import. List them before converting.
23
+ - `source.config.ts` `mdxOptions`: remark/rehype plugins that change syntax (`remarkSteps`, `remarkMdxFiles`, `remarkDirectiveAdmonition`, math).
24
+
25
+ If content comes from a CMS integration (Notion, Sanity) the repo has no MDX; use the live site.
26
+
27
+ ### From an export
28
+
29
+ None; the site is built from the repo.
30
+
31
+ ### From the live site
32
+
33
+ If the site enabled the LLM integration (https://fumadocs.dev/docs/integrations/llms), fetch `/llms.txt` for the page list and `<page-url>.md` per page; components appear as JSX. Otherwise mirror the rendered `<article>`.
34
+
35
+ ## Config → docs.json
36
+
37
+ | Fumadocs | docs.json |
38
+ | ------------------------------------------------- | --------------------------------------------------------------- |
39
+ | `nav.title` (text or JSX) | `name`; image inside it → `logo` |
40
+ | `githubUrl` | `navbar.links` entry with `type: "github"` |
41
+ | `links` (`text`, `url`, `icon`) | `navbar.links`, or `navigation.tabs` with `href` if in main row |
42
+ | `<Banner>` in a layout | `banner` |
43
+ | Root folders (`root: true`) | `navigation.tabs` |
44
+ | Root folders sharing a type (`root: "version"`) | `navigation.versions` if versions are migrated, else report |
45
+ | `i18n` (`defineI18n`) | `navigation.languages` if languages are migrated, else report |
46
+ | `icon()` handler built on `lucide-react` | `icons.library: "lucide"` |
47
+ | `loader({ baseUrl })` | none; affects URLs, see below |
48
+ | Search provider (Orama, Algolia, Mixedbread, ...) | drop and report |
49
+ | Feedback, Open Graph image routes, page actions | drop and report |
50
+ | Theme CSS / presets | `colors.primary` from the rendered CSS; rest drop and report |
51
+
52
+ ## Navigation
53
+
54
+ Each folder's `meta.json` is the nav source. Resolve every folder, then emit groups in that order:
55
+
56
+ | `meta.json` | Mintlify |
57
+ | ----------------------------------------- | --------------------------------------------------------------------------- |
58
+ | folder `title` | `group` label (fallback: the folder name as Fumadocs renders it) |
59
+ | `pages` list | `pages` in that order; with no `...`, unlisted items are not in the sidebar |
60
+ | no `pages` | items sorted alphabetically |
61
+ | `"..."` / `"z...a"` | expand to the remaining items, alphabetical / reversed |
62
+ | `"!item"` | remove `item` from the expanded rest |
63
+ | `"...folder"` | inline that folder's items here, no nested group |
64
+ | `"---Label---"`, `"---[Icon]Label---"` | close the current group; following items form a new group `Label` |
65
+ | `"[Text](url)"`, `"external:[Text](url)"` | a page with frontmatter `title` + `url: <href>`, listed at that position |
66
+ | `index.mdx` or `pagesIndex` | group `root` |
67
+ | `defaultOpen: true` | `expanded: true` on the nested group |
68
+ | `collapsible: false` | report |
69
+ | `icon` | `icon`, converted (below) |
70
+ | `root: true` + `title`, `description` | tab label; `description` only if you use `navigation.products` |
71
+ | `meta.<lang>.json` | that language's labels |
72
+
73
+ Folders in parentheses, `(name)/`, group files without adding a URL segment. Move their files up one level and keep the nav their `meta.json` defines.
74
+
75
+ Icons are names resolved by the repo's own `icon()` handler, usually PascalCase `lucide-react` exports. Convert each to its lucide.dev kebab-case name (`BookOpen` → `book-open`; strip a trailing `Icon`) and confirm it exists on lucide.dev. Drop icons you cannot confirm.
76
+
77
+ ## Content conversion
78
+
79
+ | Fumadocs | Mintlify |
80
+ | ------------------------------------------------------------------ | -------------------------------------------------------------------- |
81
+ | `<Callout>` / `type="info"` | `<Info>` |
82
+ | `type="warn"` / `"warning"` | `<Warning>` |
83
+ | `type="error"` | `<Danger>` |
84
+ | `type="success"` | `<Check>` |
85
+ | `type="idea"` | `<Tip>` |
86
+ | Callout `title` | (`mint migrate --topic conversion`, Components) |
87
+ | `:::tip[Title]` etc. (remarkDirectiveAdmonition enabled) | (`mint migrate --topic conversion`, Admonitions) |
88
+ | `<Cards>` / `<Card icon={<X />} title href>` | `<Columns cols={2}>` / `<Card icon="x" title href>` |
89
+ | `<Tabs items={[...]}>` + `<Tab value="A">` | `<Tabs>` + `<Tab title="A">`; no `value` → label from `items[i]` |
90
+ | `<Tabs defaultIndex>`; `groupId`, `persist`, `updateAnchor` | `defaultTabIndex`; drop the rest |
91
+ | `<Accordions>` / `<Accordion title id>` | `<AccordionGroup>` / `<Accordion title id>` |
92
+ | `<Steps><Step>### Title ...</Step></Steps>` | `<Steps><Step title="Title">...</Step></Steps>`, heading removed |
93
+ | `### Title [step]`, `### 1. Title` (remark-steps), `fd-steps` divs | `<Steps>` / `<Step title>` |
94
+ | `<Files>` / `<Folder name defaultOpen>` / `<File name>` | `<Tree>` / `<Tree.Folder name defaultOpen>` / `<Tree.File name>` |
95
+ | ` ```files ` fence (remark-mdx-files) | `<Tree>` |
96
+ | `<TypeTable type={{ key: { type, default, description } }}>` | one `<ResponseField name type default>` per key, description as body |
97
+ | `<include>./x.mdx</include>` | (`mint migrate --topic conversion`, Reusable content) |
98
+ | `<include>./code.ts#region</include>` | (`mint migrate --topic conversion`, Code imports) |
99
+ | `<Mermaid chart="...">` (user component) | ` ```mermaid ` fence |
100
+ | `## Heading [#custom-id]` | (`mint migrate --topic conversion`, Heading IDs) |
101
+ | `## Heading [!toc]` / `[toc]` | strip the marker; report |
102
+
103
+ Code fences:
104
+
105
+ | Fumadocs meta | Mintlify |
106
+ | ------------------------------------------------- | --------------------------------------------------------- |
107
+ | `title="x"` | `title="x"` |
108
+ | `lineNumbers` | `lines` |
109
+ | `lineNumbers=N` | `lines`; report the start offset |
110
+ | adjacent fences with `tab="A"` | one `<CodeGroup>`, each block titled `A` |
111
+ | `tab-group="..."` | drop |
112
+ | `// [!code highlight]` / `[!code focus]` comments | remove; `highlight={n}` / `focus={n}` |
113
+ | `// [!code ++]` / `[!code --]` | keep |
114
+ | `// [!code word:x]` | remove; report |
115
+ | `twoslash` | keep |
116
+ | ` ```npm ` fence | (`mint migrate --topic conversion`, Package-manager tabs) |
117
+
118
+ Imports: remove `fumadocs-ui/*`, `fumadocs-core/*` and `lucide-react` imports after converting their usages (`mint migrate --topic conversion`, Components).
119
+
120
+ Frontmatter: keep `title`, `description` (Fumadocs UI renders it under the title), `icon` (converted). `full: true` → `mode: "wide"`, report. Pages with `_openapi` frontmatter that render `<OpenAPIPage>`/`<APIPage>` are generated; delete them and follow `mint migrate --topic api`.
121
+
122
+ ## Assets
123
+
124
+ `public/` is served from the site root: `public/img/a.png` → `/img/a.png` (`mint migrate --topic conversion`, Images and files). Images imported into MDX (`import img from './a.png'`) or referenced relatively: move the file and use its root path.
125
+
126
+ ## URLs and redirects
127
+
128
+ URL = `baseUrl` + file path slugs: `dir/page.mdx` → `<baseUrl>/dir/page`, `dir/index.mdx` → `<baseUrl>/dir`, `(group)` segments dropped. With i18n, locales prefix the path unless `hideLocale` hides it (`default-locale`: default locale unprefixed; `always`: no prefix). Loader plugins may change slugs; trust the live sitemap over the file tree.
129
+
130
+ If the Mintlify site drops the `baseUrl` prefix, add a base path redirect (`mint migrate --topic navigation`, Redirects).
131
+
132
+ ## Known gaps
133
+
134
+ Report these:
135
+
136
+ - `[!toc]` / `[toc]` heading markers, `<InlineTOC>` and page-tree-driven card lists (render the list statically).
137
+ - `<auto-type-table>`, `<auto-files>`: generated at build time; render their output statically.
138
+ - `<DynamicCodeBlock>`, `<GithubInfo>`, `<ImageZoom>`, `<GraphView>`.
139
+ - Custom Shiki transformers, `[!code word:]`, line number offsets, persisted tab groups.
140
+ - `collapsible: false` folders and nested `[Text](url)` sidebar links.
141
+ - GraphQL and AsyncAPI pages generated by Fumadocs integrations.