@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.
- package/__test__/migrate.test.ts +186 -0
- package/__test__/validateRules.test.ts +36 -0
- package/bin/cli.js +35 -0
- package/bin/migrate.js +54 -0
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/bin/validate/files.js +16 -4
- package/bin/validate/mdx.js +1 -1
- package/migrate/index.md +56 -0
- package/migrate/sources/confluence.md +120 -0
- package/migrate/sources/docsify.md +128 -0
- package/migrate/sources/document360.md +117 -0
- package/migrate/sources/docus.md +136 -0
- package/migrate/sources/docusaurus.md +143 -0
- package/migrate/sources/fern.md +130 -0
- package/migrate/sources/fumadocs.md +141 -0
- package/migrate/sources/gitbook.md +120 -0
- package/migrate/sources/github-wiki.md +90 -0
- package/migrate/sources/jekyll.md +104 -0
- package/migrate/sources/mdbook.md +98 -0
- package/migrate/sources/mkdocs.md +113 -0
- package/migrate/sources/nextra.md +144 -0
- package/migrate/sources/notion.md +99 -0
- package/migrate/sources/nuxt.md +113 -0
- package/migrate/sources/pdf.md +99 -0
- package/migrate/sources/readme.md +118 -0
- package/migrate/sources/redocly.md +114 -0
- package/migrate/sources/starlight.md +136 -0
- package/migrate/sources/vitepress.md +143 -0
- package/migrate/sources/vuepress.md +153 -0
- package/migrate/topics/api.md +76 -0
- package/migrate/topics/changelog.md +47 -0
- package/migrate/topics/conversion.md +194 -0
- package/migrate/topics/discovery.md +93 -0
- package/migrate/topics/navigation.md +82 -0
- package/migrate/topics/verify.md +58 -0
- package/package.json +10 -10
- package/src/cli.tsx +47 -0
- package/src/migrate.ts +76 -0
- package/src/validate/files.ts +23 -3
- package/src/validate/mdx.ts +1 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Nextra
|
|
2
|
+
|
|
3
|
+
Docs built with Nextra (`nextra`, `nextra-theme-docs`) on Next.js. Reference: https://nextra.site/docs/file-conventions/meta-file and https://nextra.site/docs/guide/syntax-highlighting.
|
|
4
|
+
|
|
5
|
+
## Detect
|
|
6
|
+
|
|
7
|
+
- `package.json` has `nextra` and `nextra-theme-docs` (or `nextra-theme-blog`, which is a blog, not docs).
|
|
8
|
+
- `next.config.*` wraps the config with `nextra({...})`.
|
|
9
|
+
- `_meta.{js,jsx,ts,tsx}` files (`_meta.json` in old sites, `_meta.global.*` for a single-file tree).
|
|
10
|
+
- Live site: `/_next/` assets and `nextra-` CSS classes.
|
|
11
|
+
|
|
12
|
+
Then pick the generation. Config and content live in different places:
|
|
13
|
+
|
|
14
|
+
| Signal | Generation |
|
|
15
|
+
| ------------------------------------------------------------------------ | ------------ |
|
|
16
|
+
| `theme.config.{js,jsx,ts,tsx}` + content in `pages/` | Pages Router |
|
|
17
|
+
| `<Layout>` from `nextra-theme-docs` in `app/layout.*`, no `theme.config` | App Router |
|
|
18
|
+
|
|
19
|
+
## Get the source
|
|
20
|
+
|
|
21
|
+
### From the repo
|
|
22
|
+
|
|
23
|
+
- Pages Router: every `.md`/`.mdx` under `pages/` (or `src/pages/`) is a page.
|
|
24
|
+
- App Router: `content/` (or `src/content/`) served through `app/[[...mdxPath]]/page.jsx`, and/or `app/**/page.mdx`. Both can coexist; collect both.
|
|
25
|
+
- Read `next.config.*` (`basePath`, `contentDirBasePath`, `i18n`, `latex`, `redirects()`), the theme config (`theme.config.*` or the `app/layout.*` props), and `mdx-components.*` for components used without imports.
|
|
26
|
+
- i18n: read `i18n.locales` in `next.config`, then find how files are split per locale (locale-suffixed files such as `index.en.mdx`, or one folder per locale). Each locale has its own `_meta` files.
|
|
27
|
+
|
|
28
|
+
### From an export
|
|
29
|
+
|
|
30
|
+
None; the site is built from the repo.
|
|
31
|
+
|
|
32
|
+
### From the live site
|
|
33
|
+
|
|
34
|
+
No raw-markdown endpoint. Mirror the rendered `<article>` per page and read the sidebar from the HTML.
|
|
35
|
+
|
|
36
|
+
## Config â docs.json
|
|
37
|
+
|
|
38
|
+
Pages Router keys are in `theme.config.*`; App Router keys are props on `<Layout>`, `<Navbar>`, `<Footer>`, `<Banner>` in `app/layout.*`.
|
|
39
|
+
|
|
40
|
+
| Nextra | docs.json |
|
|
41
|
+
| --------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
42
|
+
| `logo` / `<Navbar logo>` (JSX) | `name` from the text, `logo` from the image |
|
|
43
|
+
| `project.link` / `<Navbar projectLink>` | `navbar.links` entry with `type: "github"` (if GitHub) |
|
|
44
|
+
| `chat.link` / `<Navbar chatLink>` | `navbar.links` entry (`type: "discord"` if Discord) |
|
|
45
|
+
| `banner.content`, `banner.dismissible` / `<Banner>` | `banner.content`, `banner.dismissible` |
|
|
46
|
+
| `footer` / `<Footer>` children | `footer.links` / `footer.socials` if it holds links; else drop and report |
|
|
47
|
+
| `head` / `<Head>` | `seo.metatags` for static tags; dynamic logic drop and report |
|
|
48
|
+
| `darkMode`, `nextThemes.defaultTheme` | `appearance` |
|
|
49
|
+
| `primaryHue`, `primarySaturation` | `colors.primary` (take the hex from the rendered CSS) |
|
|
50
|
+
| `lastUpdated` | `metadata.timestamp` |
|
|
51
|
+
| `i18n` (theme) + `i18n` (`next.config`) | `navigation.languages` if languages are migrated, else report |
|
|
52
|
+
| `latex: true` (`next.config`) | none; math renders natively |
|
|
53
|
+
| `docsRepositoryBase`, `editLink`, `feedback` | drop and report |
|
|
54
|
+
| `search`, `sidebar.*`, `toc.*`, `navigation` | drop and report |
|
|
55
|
+
| `basePath`, `contentDirBasePath`, `trailingSlash` | none; affect URLs, see below |
|
|
56
|
+
|
|
57
|
+
## Navigation
|
|
58
|
+
|
|
59
|
+
Each folder's `_meta` sets order and labels for its own children. A folder's label lives in the parent `_meta`, under the folder's key.
|
|
60
|
+
|
|
61
|
+
| `_meta` entry | Mintlify |
|
|
62
|
+
| --------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
63
|
+
| key order | `pages` order; unlisted files follow alphabetically (`index` first if unlisted) |
|
|
64
|
+
| `key: 'Label'` or `{ title }` on a page | `sidebarTitle` when it differs from the page H1 |
|
|
65
|
+
| `key: 'Label'` on a folder | `group` label for that folder |
|
|
66
|
+
| JSX title | its text |
|
|
67
|
+
| root `type: 'page'` (folder) | `navigation.tabs` entry `{ tab: title, groups }` |
|
|
68
|
+
| root `type: 'page'` with `href` | tab with `href` |
|
|
69
|
+
| `type: 'menu'` + `items` with `href` | tab with `menu: [{ item, href }]` |
|
|
70
|
+
| `type: 'separator'` with `title` | close the current group; following items form group `title` |
|
|
71
|
+
| `type: 'separator'` without `title` | drop |
|
|
72
|
+
| `display: 'hidden'` | leave out of navigation (still served) |
|
|
73
|
+
| `display: 'children'` | reproduce the rendered sidebar; report |
|
|
74
|
+
| `{ title, href }` sidebar link | top level: `navigation.global.anchors`; nested: drop and report |
|
|
75
|
+
| `theme: { layout: 'full' }` | page frontmatter `mode: "wide"`; report |
|
|
76
|
+
| other `theme` keys (`sidebar`, `toc`, `typesetting`, ...) | drop and report |
|
|
77
|
+
| `'*': {...}` | apply to every sibling, then drop |
|
|
78
|
+
| `_meta.global.*` | same rules; folder entries carry children in `items` |
|
|
79
|
+
| folder `index.mdx`, or a page with `asIndexPage: true` | group `root` |
|
|
80
|
+
|
|
81
|
+
With the default `sidebar.defaultMenuCollapseLevel` (2), top-level folders start open; if they become nested groups, set `expanded: true`.
|
|
82
|
+
|
|
83
|
+
Root `type: 'page'` entries that point at a single page (`index`, `about`) become tabs with that page, or `navbar.links` if the source shows them as utility links.
|
|
84
|
+
|
|
85
|
+
## Content conversion
|
|
86
|
+
|
|
87
|
+
| Nextra | Mintlify |
|
|
88
|
+
| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
89
|
+
| `<Callout>` / `type="default"` | `<Tip>` |
|
|
90
|
+
| `type="info"` | `<Note>` |
|
|
91
|
+
| `type="warning"` | `<Warning>` |
|
|
92
|
+
| `type="error"` | `<Danger>` |
|
|
93
|
+
| `type="important"` | `<Info>` |
|
|
94
|
+
| `type={null}` | plain paragraph |
|
|
95
|
+
| Callout `emoji` | drop, or `<Callout icon>` if the emoji carries meaning |
|
|
96
|
+
| `> [!NOTE]` etc. (rendered as callouts) | (`mint migrate --topic conversion`, GitHub alerts) |
|
|
97
|
+
| `<Tabs items={[...]}>` + `<Tabs.Tab>` / `<Tab>` | `<Tabs>` + `<Tab title={items[i]}>` |
|
|
98
|
+
| `<Tabs defaultIndex>`; `storageKey` | `defaultTabIndex`; drop |
|
|
99
|
+
| `<Cards num={n}>` + `<Cards.Card>` / `<Card icon title href arrow>` | `<Columns cols={n}>` + `<Card title href arrow>`; JSX icon â icon name or drop |
|
|
100
|
+
| `<Steps>` wrapping `##`-`######` headings | `<Steps>`; each heading and its content â `<Step title="...">` |
|
|
101
|
+
| `<FileTree>` / `<FileTree.Folder name defaultOpen>` / `<FileTree.File name>` | `<Tree>` / `<Tree.Folder>` / `<Tree.File>` (not Mintlify's `<FileTree>`) |
|
|
102
|
+
| `<Table>` | markdown table |
|
|
103
|
+
| `## Heading [#custom-id]` | `## Heading {#custom-id}` |
|
|
104
|
+
| ` ```mermaid ` | keep |
|
|
105
|
+
| ` ```math ` fence | `$$ ... $$` block |
|
|
106
|
+
| inline code with `{:lang}` suffix (`` `let x{:js}` ``) | strip the suffix |
|
|
107
|
+
|
|
108
|
+
Code fence meta:
|
|
109
|
+
|
|
110
|
+
| Nextra | Mintlify |
|
|
111
|
+
| --------------------- | --------------------------------------------------------- |
|
|
112
|
+
| `filename="x.js"` | `title="x.js"` |
|
|
113
|
+
| `{1,4-5}` | `highlight={1,4-5}` |
|
|
114
|
+
| `showLineNumbers` | `lines` |
|
|
115
|
+
| `copy` | drop |
|
|
116
|
+
| `copy=false` | `nocopy` |
|
|
117
|
+
| `/word/`, `/word/1-3` | drop; report |
|
|
118
|
+
| `npm2yarn` | (`mint migrate --topic conversion`, Package-manager tabs) |
|
|
119
|
+
|
|
120
|
+
Imports: remove `nextra/components`, `nextra-theme-docs`, `nextra/icons`, `next/link` and `next/image` after converting usages (`mint migrate --topic conversion`, Components).
|
|
121
|
+
|
|
122
|
+
Frontmatter: keep `title`, `sidebarTitle`; drop `asIndexPage` after using it for navigation. Pages often have no frontmatter: the title is the body H1.
|
|
123
|
+
|
|
124
|
+
## Assets
|
|
125
|
+
|
|
126
|
+
`public/` is served from the site root: `public/demo.png` â `/demo.png` (`mint migrate --topic conversion`, Images and files). Rewrite relative static images such as `` and imported images to that root path. `<Image src>` from `nextra/components` and `<ImageZoom src>` become a markdown image with the same `src` and `alt`.
|
|
127
|
+
|
|
128
|
+
## URLs and redirects
|
|
129
|
+
|
|
130
|
+
- Pages Router: `pages/a/b.mdx` â `/a/b`; `index` â its folder.
|
|
131
|
+
- App Router content dir: `content/a/b.mdx` â `<contentDirBasePath>/a/b`. App files: `app/a/b/page.mdx` â `/a/b`; `(group)` folders add no segment.
|
|
132
|
+
- `basePath` in `next.config` prefixes every URL. Locales prefix the path (`/<locale>/...`). `trailingSlash: true` adds a slash.
|
|
133
|
+
|
|
134
|
+
Port `async redirects()` from `next.config` and add a base path redirect if the Mintlify site drops `basePath` or `contentDirBasePath` (`mint migrate --topic navigation`, Redirects). Expand entries using `has`/`missing` or `basePath: false` to exact paths, or report them.
|
|
135
|
+
|
|
136
|
+
## Known gaps
|
|
137
|
+
|
|
138
|
+
Report these:
|
|
139
|
+
|
|
140
|
+
- `<Bleed>`, `<Playground>`, `<Banner>` outside the layout, and `nextra-theme-blog` pages.
|
|
141
|
+
- Per-page `theme` switches, `display: 'children'`, nested sidebar links, untitled separators.
|
|
142
|
+
- `/word/` substring highlighting and inline `{:lang}` highlighting.
|
|
143
|
+
- MathJax renderer and custom `latex` macros.
|
|
144
|
+
- Edit link, feedback link, dynamic `head` logic, and custom 404 pages.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Notion
|
|
2
|
+
|
|
3
|
+
Notion workspaces and pages, private or published to the web (`*.notion.site` or a custom domain). The customer exports the pages and you work on the export locally. The old pages stay on Notion, so you produce a route table instead of redirects.
|
|
4
|
+
|
|
5
|
+
## Detect
|
|
6
|
+
|
|
7
|
+
- Page URLs: `https://www.notion.so/<workspace>/<Title>-<32-hex id>` or `https://<domain>.notion.site/<Title>-<32-hex id>`; published sites can use a custom slug instead.
|
|
8
|
+
- A Markdown & CSV export ZIP holds `.md` pages and `.csv` databases whose file and folder names end in a 32-hex page id, with a folder per page that has subpages.
|
|
9
|
+
- Markdown pages contain callouts as raw HTML (`<aside>`), because Markdown has no equivalent.
|
|
10
|
+
|
|
11
|
+
## Get the source
|
|
12
|
+
|
|
13
|
+
### From the repo
|
|
14
|
+
|
|
15
|
+
None; use an export.
|
|
16
|
+
|
|
17
|
+
### From an export
|
|
18
|
+
|
|
19
|
+
Formats, options and limits: https://www.notion.com/help/export-your-content
|
|
20
|
+
|
|
21
|
+
- **Format.** Ask for Markdown & CSV with "Include subpages" and "Create folders for subpages" on, and files and images included. HTML is the fallback. Do not use PDF.
|
|
22
|
+
- **Scope.** A page export (`âĸâĸâĸ` â Export) covers that page and, with subpages, its tree. A whole-workspace export is under Settings â General (https://www.notion.com/help/workspace-settings). Either covers only pages the exporting user can access; guests need full access. On Enterprise, owners can disable export.
|
|
23
|
+
- **Delivery.** Large exports arrive as an emailed download link that expires. Ask for every part if the export is split.
|
|
24
|
+
- **Databases.** A full-page database exports as a CSV of the chosen view plus one `.md` per row. Form views do not export.
|
|
25
|
+
|
|
26
|
+
Inspect the layout before writing the transformer (`mint migrate --topic discovery`, From an export). Build an id â file index from the id suffix of every file and folder name.
|
|
27
|
+
|
|
28
|
+
**API alternative.** If the customer prefers, they can run Notion's markdown endpoint (`GET /v1/pages/<id>/markdown`) on their machine with their own integration, shared with the pages in scope. Never ask for the token. Its syntax differs from the export (`<callout>`, `<columns>`, `<synced_block>`, `<page>`, `<unknown>` for embeds and unshared content) and long pages come back `truncated`. Reference: https://developers.notion.com/guides/data-apis/working-with-markdown-content
|
|
29
|
+
|
|
30
|
+
### From the live site
|
|
31
|
+
|
|
32
|
+
Public pages render client-side and serve no raw endpoint, so scraping is unreliable. Use an export. Use the published site only to confirm which pages are public and in what order they appear.
|
|
33
|
+
|
|
34
|
+
## Config â docs.json
|
|
35
|
+
|
|
36
|
+
Notion has almost no site chrome to carry over.
|
|
37
|
+
|
|
38
|
+
| Notion | docs.json |
|
|
39
|
+
| ----------------------------------------- | --------------------------------------------------------- |
|
|
40
|
+
| Workspace or root page name | `name` |
|
|
41
|
+
| Root page icon | `favicon` (ask for a logo; page icons are usually emoji) |
|
|
42
|
+
| Site header links (Notion Sites) | `navbar.links` |
|
|
43
|
+
| Several teamspaces or root pages migrated | `navigation.tabs` or `navigation.products`, only as shown |
|
|
44
|
+
| Page cover images, fonts, full-width | drop and report |
|
|
45
|
+
| Sharing, permissions, guests | drop and report |
|
|
46
|
+
| Comments, page history, analytics | drop and report |
|
|
47
|
+
|
|
48
|
+
## Navigation
|
|
49
|
+
|
|
50
|
+
The page hierarchy is the navigation. Build it from the export's folder nesting: a page with subpages becomes a nested group whose first page is the parent page itself (`mint migrate --topic navigation`).
|
|
51
|
+
|
|
52
|
+
- The export does not record sibling order. Take it from the order of child-page links in the parent page body, then the workspace sidebar or published site as the customer sees it; ask if neither is available.
|
|
53
|
+
- Map teamspaces or separate root pages to tabs only if the source presented them as separate sections.
|
|
54
|
+
- Keep page titles verbatim as labels. Database row pages go under their database's group only if they were navigable pages on the source.
|
|
55
|
+
|
|
56
|
+
## Content conversion
|
|
57
|
+
|
|
58
|
+
Count every distinct HTML tag and block pattern in the export before mapping (`mint migrate --topic conversion`).
|
|
59
|
+
|
|
60
|
+
| Notion export | Mintlify |
|
|
61
|
+
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
62
|
+
| Page H1 | `title`; remove it from the body |
|
|
63
|
+
| Property lines under the title (database rows) | drop and report, unless the customer wants them as a table |
|
|
64
|
+
| Callout (`<aside>` with an emoji) | `<Note>`, `<Info>`, `<Tip>`, `<Warning>`, `<Danger>` by meaning; ask for the emoji â type map |
|
|
65
|
+
| Toggle (`<details>` or a nested list item; inspect) | `<Accordion title="...">` |
|
|
66
|
+
| Toggle heading | heading followed by its content, or `<Accordion>` if the customer prefers it collapsed |
|
|
67
|
+
| Columns | `<Columns>`, one child per column; unwrap if the content does not fit |
|
|
68
|
+
| Code block with language | fence with the language; caption â title |
|
|
69
|
+
| Equation (`$$...$$`, inline `$...$`) | LaTeX, unchanged |
|
|
70
|
+
| To-do (`- [ ]`, `- [x]`) | list; prefix each item with its status |
|
|
71
|
+
| Table, simple table | markdown table; HTML table made MDX-safe if cells hold blocks |
|
|
72
|
+
| Synced block (duplicated wherever it appears) | snippet (`mint migrate --topic conversion`, Reusable content) |
|
|
73
|
+
| Link to a page (`Title%20<id>.md`) | root-absolute path via the id â path index (`mint migrate --topic conversion`, Links) |
|
|
74
|
+
| Page mention or link to a page outside the export | absolute Notion URL; report |
|
|
75
|
+
| Inline or linked database view | markdown table of the CSV, or a list of links to its row pages; report |
|
|
76
|
+
| Bookmark | link with its title |
|
|
77
|
+
| Embed (YouTube, Figma, Loom, Google Drive, and so on) | video embed where supported, else a link; report |
|
|
78
|
+
| Table of contents block | drop |
|
|
79
|
+
| Breadcrumb block | drop |
|
|
80
|
+
|
|
81
|
+
Decode URL-encoded link targets (`%20`) before matching ids. Strip the id suffix from every file name and slug; slugify titles for new paths.
|
|
82
|
+
|
|
83
|
+
## Assets
|
|
84
|
+
|
|
85
|
+
- Images and files sit in a folder next to each page, named after the page. Copy them to `images/<page-path>/` (images) or a downloads folder (other files) and rewrite references (`mint migrate --topic conversion`, Images and files).
|
|
86
|
+
- Links to Notion-hosted files (`secure.notion-static.com`, signed `amazonaws.com` URLs) are signed and expire. Download them during conversion, never hotlink. Reference: https://developers.notion.com/reference/file-object
|
|
87
|
+
- Notion icons and covers that are emoji or Notion's built-in images are not files; drop them.
|
|
88
|
+
|
|
89
|
+
## URLs and redirects
|
|
90
|
+
|
|
91
|
+
Old URLs stay on Notion, so `redirects` cannot catch them. Produce `route-table.csv` as in `mint migrate --from confluence` (URLs and redirects), keyed by the 32-hex page id: `page_id, old_url, new_path, title`. Take `old_url` from the published site or the page's share link; title segments in Notion URLs change on rename, the id does not. If the customer moves a custom domain from Notion Sites to Mintlify, add `redirects` for the old paths instead (`mint migrate --topic navigation`, Redirects). Site settings: https://www.notion.com/help/public-pages-and-web-publishing
|
|
92
|
+
|
|
93
|
+
## Known gaps
|
|
94
|
+
|
|
95
|
+
- Databases: views, filters, sorts, relations, rollups, formulas and properties beyond the title.
|
|
96
|
+
- Synced blocks no longer sync with Notion; the snippet is the single source from now on.
|
|
97
|
+
- Comments, page history, permissions, guests and sharing settings.
|
|
98
|
+
- Notion-specific embeds and blocks (buttons, forms, AI blocks, link previews) with no equivalent.
|
|
99
|
+
- Pages the exporting user could not access, and pages outside the exported tree.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Nuxt Content
|
|
2
|
+
|
|
3
|
+
Docs built with Nuxt and the Nuxt Content module, including Docus and Nuxt UI Pro docs templates.
|
|
4
|
+
|
|
5
|
+
## Detect
|
|
6
|
+
|
|
7
|
+
- Rendered HTML contains `<div id="__nuxt">` and sets `window.__NUXT__`.
|
|
8
|
+
- Static assets load from `/_nuxt/`.
|
|
9
|
+
- `<page-url>/_payload.json` returns JSON instead of 404.
|
|
10
|
+
- In a repo: `nuxt.config.ts` with `@nuxt/content` (or `@nuxt-themes/docus`) in `modules`, and pages under `content/`.
|
|
11
|
+
|
|
12
|
+
## Get the source
|
|
13
|
+
|
|
14
|
+
### From the repo
|
|
15
|
+
|
|
16
|
+
Pages are markdown in `content/`, written in MDC syntax. Nav order comes from numeric filename prefixes (`1.getting-started/2.installation.md`) and `.navigation.yml` / `_dir.yml` files. Config lives in `nuxt.config.ts` and `app.config.ts`.
|
|
17
|
+
|
|
18
|
+
### From an export
|
|
19
|
+
|
|
20
|
+
None; the site is built from the repo.
|
|
21
|
+
|
|
22
|
+
### From the live site
|
|
23
|
+
|
|
24
|
+
Each page's `_payload.json` holds the page body as a structured AST ("minimark": `{ type, tag, props, children }` nodes, or compact arrays `[tag, props, ...children]`) plus, usually, the site navigation tree. Convert from this AST, not from rendered HTML.
|
|
25
|
+
|
|
26
|
+
Mirror `<page-url>/_payload.json` for every page (`mint migrate --topic discovery`, Mirror the raw source). Spot-check one:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -sS https://docs.example.com/guide/setup/_payload.json | python3 -m json.tool | head -60
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
It should show element nodes (`"tag": "h1"` and so on), not HTML. If `_payload.json` 404s site-wide but the site is still Nuxt, look for `_payload.js` and extract the embedded payload with a small Node script before falling back to HTML. Some Nuxt Content sites also expose raw markdown or a query API under `/api/_content/` or `/__nuxt_content/`; prefer raw markdown if it is served.
|
|
33
|
+
|
|
34
|
+
Pick one URL form during inventory. `/foo` and `/foo/` may both return 200, but usually only one serves `_payload.json`. Mixing them creates duplicate mirror files.
|
|
35
|
+
|
|
36
|
+
## Config â docs.json
|
|
37
|
+
|
|
38
|
+
| Nuxt | docs.json |
|
|
39
|
+
| ---------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
40
|
+
| `app.config.ts` site name / `seo.siteName` | `name` |
|
|
41
|
+
| `app.config.ts` header logo (light/dark) | `logo.light`, `logo.dark` |
|
|
42
|
+
| `public/favicon.*` | `favicon` |
|
|
43
|
+
| `app.config.ts` `ui.primary` / theme colors | `colors.primary` (resolve the named color to its hex from the rendered CSS) |
|
|
44
|
+
| Header links (`header.links`) | `navbar.links`, or `navigation.tabs` with `href` if they sit in the main row |
|
|
45
|
+
| Footer links / socials | `footer.links`, `footer.socials` |
|
|
46
|
+
| Top-level content folders shown as header tabs | `navigation.tabs` |
|
|
47
|
+
| `seo` / `useSeoMeta` defaults | `seo.metatags` |
|
|
48
|
+
| `content.highlight` themes | drop and report |
|
|
49
|
+
| Search (Algolia DocSearch, built-in) | drop and report |
|
|
50
|
+
| Analytics modules, custom plugins, middleware | drop and report |
|
|
51
|
+
| i18n (`@nuxtjs/i18n`) | `navigation.languages` if the user migrates other languages, else report |
|
|
52
|
+
|
|
53
|
+
## Navigation
|
|
54
|
+
|
|
55
|
+
Use the navigation tree from `_payload.json` (look for a `navigation` key at the top level or under `data`) or, in a repo, the ordered `content/` tree. Each node has `title`, `_path` or `path`, and `children`. Nodes with children become nested groups; their own page, if any, goes first in the group.
|
|
56
|
+
|
|
57
|
+
Labels: the node `title` is the sidebar label. If it differs from the page H1, set `sidebarTitle`. Drop numeric prefixes from paths and labels. Respect `navigation: false` in page front matter (page exists but is hidden) and `navigation.title` / `navigation.icon` overrides. Nuxt icons are usually Iconify names (`mint migrate --topic conversion`, Icons).
|
|
58
|
+
|
|
59
|
+
## Content conversion
|
|
60
|
+
|
|
61
|
+
Walk the AST and emit markdown and Mintlify components. Count every distinct `tag` across the mirror first (`mint migrate --topic conversion`):
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import json, glob, collections
|
|
65
|
+
tags = collections.Counter()
|
|
66
|
+
def walk(n):
|
|
67
|
+
if isinstance(n, dict):
|
|
68
|
+
if 'tag' in n: tags[n['tag']] += 1
|
|
69
|
+
for v in n.values(): walk(v)
|
|
70
|
+
elif isinstance(n, list):
|
|
71
|
+
if n and isinstance(n[0], str) and len(n) > 1 and isinstance(n[1], dict): tags[n[0]] += 1
|
|
72
|
+
for v in n: walk(v)
|
|
73
|
+
for f in glob.glob('mirror/*.json'):
|
|
74
|
+
walk(json.load(open(f)))
|
|
75
|
+
print(tags.most_common())
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| MDC / component | Mintlify |
|
|
79
|
+
| ----------------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
80
|
+
| `::callout`, `::note`, `::tip`, `::warning`, `::caution`, `::alert{type=...}` | `<Note>`, `<Tip>`, `<Warning>`, `<Danger>`, `<Info>` by meaning |
|
|
81
|
+
| `::steps`, `::Steps` with `###` children | `<Steps>` / `<Step title>` |
|
|
82
|
+
| `::tabs` / `::code-group` | `<Tabs>` / `<CodeGroup>` |
|
|
83
|
+
| `::card`, `::card-group`, `::card-grid` | `<Card>`, `<CardGroup>` |
|
|
84
|
+
| `::collapsible`, `::accordion` | `<Accordion>`, `<AccordionGroup>` |
|
|
85
|
+
| `::field`, `::field-group` | `<ParamField>` / `<ResponseField>` |
|
|
86
|
+
| `::badge`, `:badge[...]` | `<Badge>` |
|
|
87
|
+
| `:icon{name=...}` | `<Icon icon="...">` (`mint migrate --topic conversion`, Icons) |
|
|
88
|
+
| `pre` with `filename`, `highlights` props | fenced block with filename and `{1,3}` line highlights |
|
|
89
|
+
| `prose-*` tags (`prose-h2`, `prose-a`, ...) | the plain markdown element |
|
|
90
|
+
| Site-specific components (custom `components/content/*.vue`) | (`mint migrate --topic conversion`, Components) |
|
|
91
|
+
|
|
92
|
+
Hazards:
|
|
93
|
+
|
|
94
|
+
- Inline MDC attributes (`text{.class}`, `[link]{target=_blank}`) must be stripped; they are not MDX.
|
|
95
|
+
- Props in the AST (`:prop` bindings, `v-bind`) are data, not text. Do not dump them into the page.
|
|
96
|
+
- Front matter blocks inside components (`---` YAML inside `::card`) are props.
|
|
97
|
+
- Vue components with slots (`#title`, `#default`) map to component props and children.
|
|
98
|
+
|
|
99
|
+
## Assets
|
|
100
|
+
|
|
101
|
+
Images are under `public/` in the repo, or `/_nuxt/` and `/images/` on the live site (`mint migrate --topic conversion`, Images and files). Nuxt Image (`<NuxtImg>`, `/_ipx/` URLs) serves resized variants: strip the `/_ipx/<modifiers>/` prefix to get the original file.
|
|
102
|
+
|
|
103
|
+
## URLs and redirects
|
|
104
|
+
|
|
105
|
+
Nuxt Content paths are the `content/` paths with numeric prefixes and `index` removed (`content/1.guide/0.index.md` â `/guide`). Keep those paths. Port redirects defined in `nuxt.config.ts` `routeRules` (`mint migrate --topic navigation`, Redirects).
|
|
106
|
+
|
|
107
|
+
## Known gaps
|
|
108
|
+
|
|
109
|
+
- Custom Vue components and interactive playgrounds: static content only.
|
|
110
|
+
- `app.config.ts` UI theming beyond primary color, logo and fonts.
|
|
111
|
+
- Built-in or Algolia search configuration, analytics modules.
|
|
112
|
+
- Content queries rendered on the page (`ContentList`, `ContentQuery`): migrate the rendered output as static content.
|
|
113
|
+
- Iconify icons with no Font Awesome equivalent.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# PDF
|
|
2
|
+
|
|
3
|
+
One or more PDF files the customer provides locally: manuals, guides, exported specs. There is no navigation data or URL space, so structure comes from the PDF outline and headings.
|
|
4
|
+
|
|
5
|
+
## Detect
|
|
6
|
+
|
|
7
|
+
- The customer points you at `.pdf` files, or the current directory holds them.
|
|
8
|
+
- Check each file before choosing a method:
|
|
9
|
+
- `pdfinfo file.pdf` for page count and producer.
|
|
10
|
+
- `pdffonts file.pdf`: no fonts listed means scanned pages (images only).
|
|
11
|
+
- `pdftotext -f 1 -l 3 file.pdf - | head`: empty or garbled output also means scanned or broken text encoding.
|
|
12
|
+
|
|
13
|
+
## Get the source
|
|
14
|
+
|
|
15
|
+
### From the repo
|
|
16
|
+
|
|
17
|
+
Not applicable; the customer provides the PDF files.
|
|
18
|
+
|
|
19
|
+
### From an export
|
|
20
|
+
|
|
21
|
+
The PDFs are the source. Copy them unchanged into `mirror/` and work from the copies.
|
|
22
|
+
|
|
23
|
+
Extract in this order of preference:
|
|
24
|
+
|
|
25
|
+
1. **Native PDF reading**, if your tool reads PDFs directly with layout. Still render pages to images for table and figure checks (below).
|
|
26
|
+
2. **PyMuPDF** (`pip install pymupdf`, imported as `fitz`) for structure. `page.get_text("dict")` returns blocks, lines and spans with font name, size and flags (bold, italic, monospace); use these to rebuild headings and code. `page.find_tables()` locates tables.
|
|
27
|
+
3. **Poppler** for plain text: `pdftotext -layout -f N -l M file.pdf out.txt` keeps columns and table alignment; `pdftohtml -xml file.pdf out` gives positioned text with font specs when PyMuPDF is unavailable.
|
|
28
|
+
|
|
29
|
+
Render each page to an image for checking: `pdftoppm -png -r 110 -f N -l N file.pdf mirror/pages/p` or PyMuPDF `page.get_pixmap(dpi=110).save(...)`.
|
|
30
|
+
|
|
31
|
+
**Scanned PDFs.** Run OCR into a new file and extract from that: `ocrmypdf --skip-text file.pdf mirror/file.ocr.pdf` (add `-l <lang>` for non-English). Mark every page converted from OCR in the manifest `notes` as `ocr` and list them in the report; OCR text needs a human proofread.
|
|
32
|
+
|
|
33
|
+
Encrypted PDFs that refuse extraction: ask the customer for an unlocked copy. Never try to bypass the protection.
|
|
34
|
+
|
|
35
|
+
### From the live site
|
|
36
|
+
|
|
37
|
+
Not applicable.
|
|
38
|
+
|
|
39
|
+
## Config â docs.json
|
|
40
|
+
|
|
41
|
+
| PDF | docs.json |
|
|
42
|
+
| ------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
43
|
+
| Document title (title page or metadata) | `name`, if the customer has no product name to use |
|
|
44
|
+
| Logo on the title page | `logo`, only if the customer confirms it |
|
|
45
|
+
| Several PDFs | one group per PDF, or `navigation.tabs` if they are separate manuals |
|
|
46
|
+
| Title page, copyright page, revision history | a page only if it has content readers need; else exclude with a reason |
|
|
47
|
+
| Printed table of contents, index, list of figures | drop; navigation and search replace them |
|
|
48
|
+
| Running headers, footers, page numbers | drop |
|
|
49
|
+
|
|
50
|
+
## Navigation
|
|
51
|
+
|
|
52
|
+
The outline (bookmarks) is the navigation data:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import fitz
|
|
56
|
+
for level, title, page in fitz.open("mirror/file.pdf").get_toc():
|
|
57
|
+
print(level, page, title)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Without PyMuPDF, `qpdf --json --json-key=outlines file.pdf` exposes the same outline.
|
|
61
|
+
|
|
62
|
+
- Level 1 entries become groups (or pages, if they have no children); deeper levels become nested groups and pages. Keep labels verbatim.
|
|
63
|
+
- Choose a page split depth (usually level 2) and apply it uniformly. Each page covers from its outline entry's page to the page before the next entry at the same or higher level.
|
|
64
|
+
- An outline entry can start mid-page; split at its heading, not at the page break.
|
|
65
|
+
- No outline: derive the tree from heading font sizes (largest size = level 1) and confirm the result with the customer before converting. The printed table of contents is a fallback source of titles and page numbers.
|
|
66
|
+
|
|
67
|
+
## Content conversion
|
|
68
|
+
|
|
69
|
+
Never paraphrase, summarize or reword. Every word on a page comes from the PDF.
|
|
70
|
+
|
|
71
|
+
- **Page furniture.** Strip running headers, footers and page numbers: lines that repeat at the same position on most pages. Detect them by position and repetition, not by guessing text.
|
|
72
|
+
- **Line and page breaks.** Rejoin lines inside paragraphs; rejoin paragraphs split across a page break. Remove end-of-line hyphenation only where the joined word is a real word (`config-\nuration` â `configuration`); keep hyphens in compounds (`command-\nline` stays `command-line` when that is how the document spells it elsewhere).
|
|
73
|
+
- **Headings.** Map font size and weight to heading levels per document. The page's own title becomes frontmatter `title` (`mint migrate --topic conversion`, Frontmatter).
|
|
74
|
+
- **Lists.** Rebuild bullets (`âĸ`, `â`, `âĒ`) and numbered items, including nesting by indent. Join wrapped list lines.
|
|
75
|
+
- **Tables.** The main hazard. Extracted text loses cell boundaries, merges multi-line cells and splits tables across pages. Rebuild each table, then compare it cell by cell against the rendered page image. Merge continued tables (repeated header row on the next page). Use an HTML table only where cells span rows or columns.
|
|
76
|
+
- **Code.** Monospace spans become fenced blocks. Keep indentation and line breaks exactly; do not rejoin code lines. Add a language only when the document states it or it is unambiguous.
|
|
77
|
+
- **Callouts.** Boxed "Note", "Caution", "Warning" or "Tip" paragraphs map to the matching callout component, only where the label is printed.
|
|
78
|
+
- **Ligatures and characters.** Normalize ligatures (`īŦ`, `īŦ`), curly quotes in code, and non-breaking spaces. Unknown glyphs (`īŋŊ`) mean an encoding problem: re-extract that page with another tool or OCR it.
|
|
79
|
+
- **Cross-references.** "See section 4.2" and "on page 37" become links to the migrated page that holds that content; keep the original wording.
|
|
80
|
+
- **Footnotes.** Move each footnote to the end of its page's section, keeping its number.
|
|
81
|
+
|
|
82
|
+
## Assets
|
|
83
|
+
|
|
84
|
+
- Extract embedded images per page: `pdfimages -png -f N -l N file.pdf images/<page-path>/fig` (use `-all` to keep original formats).
|
|
85
|
+
- Vector diagrams are not images: crop the region from a high-DPI render (`page.get_pixmap(clip=rect, dpi=200)`).
|
|
86
|
+
- Alt text comes from the figure caption, verbatim. No caption means alt text from the nearest heading plus "figure"; record it in the report. Keep the caption under the image.
|
|
87
|
+
- Drop decorative images (logos repeated on every page, rules, backgrounds).
|
|
88
|
+
|
|
89
|
+
## URLs and redirects
|
|
90
|
+
|
|
91
|
+
PDFs have no URLs, so there are no redirects. Instead, record the page range of every migrated page in the manifest, using `source_url` for the file and page range: `"source_url": "manual.pdf#pages=12-18"`. Every page of every PDF maps to exactly one migrated page or is `excluded` with a reason (title page, printed table of contents, blank page). If the customer links to the PDF from elsewhere, tell them which new page replaces each section.
|
|
92
|
+
|
|
93
|
+
## Known gaps
|
|
94
|
+
|
|
95
|
+
- OCR accuracy on scanned pages.
|
|
96
|
+
- Complex tables (merged cells, rotated headers, multi-page tables) need manual review against the page image.
|
|
97
|
+
- Vector diagrams become raster crops.
|
|
98
|
+
- Form fields, annotations, embedded attachments and hyperlinks inside the PDF may not survive extraction; check with `pdfinfo` and PyMuPDF `page.get_links()` and report what is lost.
|
|
99
|
+
- Equations: rebuild as LaTeX only where the text is extractable; otherwise use an image of the equation and report it.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# ReadMe
|
|
2
|
+
|
|
3
|
+
Developer hubs hosted by ReadMe (`*.readme.io` or a custom domain): guides, API reference, recipes, custom pages and changelog.
|
|
4
|
+
|
|
5
|
+
## Detect
|
|
6
|
+
|
|
7
|
+
- Rendered HTML loads images from `files.readme.io`.
|
|
8
|
+
- URLs use `/docs/<slug>`, `/reference/<slug>`, `/recipes/<slug>`, `/page/<slug>` and `/changelog/<slug>`, optionally behind a version or project segment (`/main/docs/...`, `/v2.0/docs/...`).
|
|
9
|
+
- Page markdown contains emoji callouts (`> đ`), `[block:...]` blocks, `<<variable>>` or `(doc:slug)` links.
|
|
10
|
+
- In a repo: top-level `docs/`, `reference/`, `recipes/`, `custom_pages/`, `custom_blocks/`, `changelogs/` and `_order.yaml` files.
|
|
11
|
+
|
|
12
|
+
## Get the source
|
|
13
|
+
|
|
14
|
+
Mintlify's guide for this platform: https://www.mintlify.com/docs/migration/readme.md
|
|
15
|
+
|
|
16
|
+
### From the repo
|
|
17
|
+
|
|
18
|
+
A Git sync repo (bi-directional sync): one repo per project, one branch per ReadMe version. https://docs.readme.com/main/docs/bi-directional-sync. Layout: https://docs.readme.com/main/docs/documentation-structure
|
|
19
|
+
|
|
20
|
+
- A page with children is a folder with `index.md`, the children, and `_order.yaml`.
|
|
21
|
+
- `_order.yaml` is a flat list of child slugs (no extension, never `index`) in sidebar order.
|
|
22
|
+
- `reference/` holds the OpenAPI files and endpoint pages; endpoint frontmatter `api.file` + `api.operationId` ties a page to an operation.
|
|
23
|
+
|
|
24
|
+
### From an export
|
|
25
|
+
|
|
26
|
+
Either of these, run by the customer per version, with the same layout as the repo:
|
|
27
|
+
|
|
28
|
+
- ZIP export from the Branch menu, emailed to the customer. It includes OpenAPI files but not images. https://docs.readme.com/main/docs/exporting-data
|
|
29
|
+
- `rdme docs export <folder>` (and `rdme reference export`) with their own API key. https://github.com/readmeio/rdme
|
|
30
|
+
|
|
31
|
+
Export every maintained version. Hidden and unpublished pages are only in the repo or an export.
|
|
32
|
+
|
|
33
|
+
### From the live site
|
|
34
|
+
|
|
35
|
+
`<page-url>.md` returns markdown; `llms.txt` at the site root and per project lists pages. Quirks (`mint migrate --topic discovery`, Mirror the raw source):
|
|
36
|
+
|
|
37
|
+
- Strip the generated frontmatter block (`updatedAt`, `agentTools`) at the top and the `# Sibling pages` / `# What's Next` sections at the end.
|
|
38
|
+
- Reference `.md` pages embed the operation's spec under a `# OpenAPI definition` JSON block. Extract it as data; it is not page content.
|
|
39
|
+
- The changelog index `.md` is a link list, not an entry.
|
|
40
|
+
|
|
41
|
+
## Config â docs.json
|
|
42
|
+
|
|
43
|
+
| ReadMe | docs.json |
|
|
44
|
+
| ---------------------------------------------------- | --------------------------------------------------- |
|
|
45
|
+
| Project name | `name` |
|
|
46
|
+
| Logo (light/dark), favicon | `logo.light`, `logo.dark`, `favicon` |
|
|
47
|
+
| Brand / theme colors | `colors.primary` |
|
|
48
|
+
| Top navigation sections (Guides, API Reference, ...) | `navigation.tabs` |
|
|
49
|
+
| Header links | `navbar.links` |
|
|
50
|
+
| Versions | `navigation.versions` if the customer migrates them |
|
|
51
|
+
| Glossary | drop; terms become `<Tooltip>` at use sites |
|
|
52
|
+
| Custom CSS / JS, custom HTML header/footer | drop and report |
|
|
53
|
+
| Personalized docs, JWT login, API key injection | drop and report |
|
|
54
|
+
| Metrics, Owlbot AI, suggested edits, discussions | drop and report |
|
|
55
|
+
|
|
56
|
+
## Navigation
|
|
57
|
+
|
|
58
|
+
- One tab per hub section the source shows (Guides, Recipes, API Reference, Changelog, custom pages).
|
|
59
|
+
- `docs/` category folders become groups in folder order; inside each folder, `_order.yaml` sets page order.
|
|
60
|
+
- A folder's `index.md` is the first page of its nested group.
|
|
61
|
+
- From the live site, rebuild the tree from each section's rendered sidebar.
|
|
62
|
+
- Frontmatter `hidden: true` pages stay reachable but out of navigation; (`mint migrate --topic navigation`, Structure rules).
|
|
63
|
+
- Link pages (frontmatter `link.url`) become navigation links.
|
|
64
|
+
|
|
65
|
+
## Content conversion
|
|
66
|
+
|
|
67
|
+
| ReadMe | Mintlify |
|
|
68
|
+
| ------------------------------------------------------ | --------------------------------------------------------------------------------------- |
|
|
69
|
+
| Blockquote starting `đ` or `âšī¸` | `<Info>` |
|
|
70
|
+
| `đ` or `â
` | `<Check>` |
|
|
71
|
+
| `đ§` or `â ī¸` | `<Warning>` |
|
|
72
|
+
| `âī¸` or `đ` | `<Danger>` |
|
|
73
|
+
| Callout title (text after the emoji on the first line) | bold first line (`mint migrate --topic conversion`, Components) |
|
|
74
|
+
| `<Callout icon theme>` | callout by `theme`, as above |
|
|
75
|
+
| Consecutive fences with no blank line between them | `<CodeGroup>`; the text after the language is the tab title |
|
|
76
|
+
| `<Tabs>`, `<Accordion>`, `<Cards>`, `<Columns>` | `<Tabs>`, `<Accordion>`, `<CardGroup>`, `<Columns>` |
|
|
77
|
+
| `[title](url "@embed")`, `<Embed>` | video embed if supported, else a link |
|
|
78
|
+
| `[block:callout]` | callout by its theme |
|
|
79
|
+
| `[block:code]` | fences, or `<CodeGroup>` for several |
|
|
80
|
+
| `[block:image]` | image with caption |
|
|
81
|
+
| `[block:parameters]` / `[block:table]` | markdown table built from the `data` keys |
|
|
82
|
+
| `[block:api-header]` | heading |
|
|
83
|
+
| `[block:html]` | the HTML, made MDX-safe |
|
|
84
|
+
| `[block:embed]` | as `@embed` |
|
|
85
|
+
| `<<glossary:term>>`, `<Glossary>term</Glossary>` | `<Tooltip tip="<definition from the glossary>">term</Tooltip>` |
|
|
86
|
+
| `<<name>>`, `{user.name}` (user variables) | the variable's default value if the customer wants it inline, else `` `name` ``; report |
|
|
87
|
+
| `(doc:slug)`, `(ref:slug)` links | root-absolute path of the migrated page |
|
|
88
|
+
| Reusable content / custom blocks (`custom_blocks/`) | snippet (`mint migrate --topic conversion`, Reusable content) |
|
|
89
|
+
| Custom MDX components | static rendering; report |
|
|
90
|
+
|
|
91
|
+
Legacy `[block:TYPE]` blocks wrap JSON terminated by `[/block]`; parse the JSON, do not regex the body. Other link schemes of the form `(<word>:slug)` may exist; count them (`mint migrate --topic conversion`).
|
|
92
|
+
|
|
93
|
+
Frontmatter: `excerpt` is the subtitle shown under the title, so it maps to `description`. `deprecated: true` maps to `deprecated: true`. `metadata.robots` containing `noindex` maps to `noindex: true`. `next.pages` is the "What's Next" list; keep it as links at the end of the page. Drop `metadata.image` and report it.
|
|
94
|
+
|
|
95
|
+
**API reference.** Endpoint pages are hand-written prose around a spec. Collect the spec files from `reference/` (or merge the per-page `# OpenAPI definition` fragments), then attach each operation to its migrated page with `openapi:` frontmatter at the page's original path. Do not also add a generated API tab for the same spec. See `mint migrate --topic api`.
|
|
96
|
+
|
|
97
|
+
**Recipes.** Interactive step-through code walkthroughs. Migrate as a page with `<Steps>` around the steps and the full code in a fence; report the lost interactivity.
|
|
98
|
+
|
|
99
|
+
**Changelog.** One `<Update>` page per `mint migrate --topic changelog`. Dates: in a Git export, frontmatter `date`; on the live site, `"created_at"` in the JSON embedded in each entry's HTML page. Tags: the entry `type` (Added, Fixed, Improved, Deprecated, Removed) as shown on the source.
|
|
100
|
+
|
|
101
|
+
## Assets
|
|
102
|
+
|
|
103
|
+
The ZIP export and Git repo reference images by `https://files.readme.io/...` URL without the files (`mint migrate --topic conversion`, Images and files). Look in page bodies, `[block:image]` JSON and custom pages; images used only in custom pages may need the rendered page to find.
|
|
104
|
+
|
|
105
|
+
## URLs and redirects
|
|
106
|
+
|
|
107
|
+
- Keep `/docs/<slug>`, `/reference/<slug>`, `/recipes/<slug>`, `/page/<slug>` paths. ReadMe slugs are flat, so nested navigation does not mean nested URLs; keep the flat path.
|
|
108
|
+
- Guides and reference pages can share a slug; the section prefix keeps them distinct.
|
|
109
|
+
- Default-version URLs omit the version segment; versioned URLs include it. Redirect the versioned form to whichever path you keep.
|
|
110
|
+
- Every `/changelog/<slug>` redirects to the consolidated changelog page.
|
|
111
|
+
|
|
112
|
+
## Known gaps
|
|
113
|
+
|
|
114
|
+
- Try It API explorer state, personalized API keys and per-user variables.
|
|
115
|
+
- Recipe step-through interactivity.
|
|
116
|
+
- Custom pages written in HTML with page-level CSS.
|
|
117
|
+
- Owlbot, metrics, suggested edits and discussion threads.
|
|
118
|
+
- Hidden or beta versions the customer did not export.
|