blume 2.1.3 → 2.2.1
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/AGENTS.md +1 -1
- package/CHANGELOG.md +134 -0
- package/README.md +4 -4
- package/dist/cli/{chunk-y4msrwm9.js → chunk-080mfch6.js} +15 -15
- package/dist/cli/{chunk-gfc5fqvf.js → chunk-1ch3ct3r.js} +18 -18
- package/dist/cli/{chunk-gfc5fqvf.js.map → chunk-1ch3ct3r.js.map} +1 -1
- package/dist/cli/{chunk-32khwcb6.js → chunk-2ssh60qh.js} +42 -69
- package/dist/cli/{chunk-32khwcb6.js.map → chunk-2ssh60qh.js.map} +9 -10
- package/dist/cli/{chunk-9qzgg6mj.js → chunk-34wap3ed.js} +3 -3
- package/dist/cli/{chunk-k3gr1nm9.js → chunk-40vk8kgf.js} +13 -16
- package/dist/cli/{chunk-k3gr1nm9.js.map → chunk-40vk8kgf.js.map} +3 -3
- package/dist/cli/chunk-487b95qy.js +329 -0
- package/dist/cli/chunk-487b95qy.js.map +13 -0
- package/dist/cli/chunk-4zxh25hc.js +157 -0
- package/dist/cli/chunk-4zxh25hc.js.map +10 -0
- package/dist/cli/chunk-69rjf786.js +146 -0
- package/dist/cli/chunk-69rjf786.js.map +11 -0
- package/dist/cli/{chunk-dqhg54mr.js → chunk-9h8mh2tk.js} +3 -3
- package/dist/cli/{chunk-dqhg54mr.js.map → chunk-9h8mh2tk.js.map} +2 -2
- package/dist/cli/{chunk-bqxaqn5p.js → chunk-9jqmq5hv.js} +8 -8
- package/dist/cli/{chunk-bqxaqn5p.js.map → chunk-9jqmq5hv.js.map} +1 -1
- package/dist/cli/{chunk-dv2z0rzf.js → chunk-aafhwx74.js} +38 -13
- package/dist/cli/{chunk-dv2z0rzf.js.map → chunk-aafhwx74.js.map} +5 -4
- package/dist/cli/{chunk-desvm72z.js → chunk-b680sv30.js} +22 -26
- package/dist/cli/chunk-b680sv30.js.map +13 -0
- package/dist/cli/{chunk-0w6hs479.js → chunk-beb0z983.js} +30 -18
- package/dist/cli/chunk-beb0z983.js.map +10 -0
- package/dist/cli/{chunk-1f882900.js → chunk-c5bjxq8v.js} +2 -2
- package/dist/cli/chunk-e1n41w9m.js +155 -0
- package/dist/cli/chunk-e1n41w9m.js.map +11 -0
- package/dist/cli/{chunk-sc93apfs.js → chunk-etckvbrh.js} +17 -17
- package/dist/cli/{chunk-sc93apfs.js.map → chunk-etckvbrh.js.map} +2 -2
- package/dist/cli/{chunk-bxwhtvw8.js → chunk-f260jdrn.js} +5 -5
- package/dist/cli/{chunk-74wfhv79.js → chunk-fnxgtjeq.js} +1 -1
- package/dist/cli/{chunk-ms9z66nz.js → chunk-gwy55cx3.js} +2 -2
- package/dist/cli/{chunk-ms9z66nz.js.map → chunk-gwy55cx3.js.map} +2 -2
- package/dist/cli/{chunk-dhwtqnnd.js → chunk-gxhcf2hs.js} +2 -2
- package/dist/cli/{chunk-tfycddbt.js → chunk-h0qwdbem.js} +2 -2
- package/dist/cli/{chunk-nbyvgnnm.js → chunk-hktq4j5r.js} +109 -49
- package/dist/cli/chunk-hktq4j5r.js.map +36 -0
- package/dist/cli/{chunk-twy7psdz.js → chunk-hn3g2b89.js} +14 -10
- package/dist/cli/chunk-hn3g2b89.js.map +10 -0
- package/dist/cli/{chunk-j1x92mx9.js → chunk-j4nfgn2j.js} +1 -1
- package/dist/cli/{chunk-dpy8qdjf.js → chunk-k45sq16q.js} +74 -183
- package/dist/cli/chunk-k45sq16q.js.map +18 -0
- package/dist/cli/{chunk-5cmts6dv.js → chunk-kmswjxj9.js} +7 -7
- package/dist/cli/{chunk-5cmts6dv.js.map → chunk-kmswjxj9.js.map} +1 -1
- package/dist/cli/{chunk-36bxs9c7.js → chunk-nqna8dzp.js} +27 -23
- package/dist/cli/chunk-nqna8dzp.js.map +10 -0
- package/dist/cli/{chunk-a57yh0h9.js → chunk-p834rkcn.js} +7 -7
- package/dist/cli/{chunk-a57yh0h9.js.map → chunk-p834rkcn.js.map} +1 -1
- package/dist/cli/{chunk-60hz265r.js → chunk-ppa6mg4d.js} +24 -11
- package/dist/cli/chunk-ppa6mg4d.js.map +10 -0
- package/dist/cli/{chunk-s0bdnc7v.js → chunk-q1wwrxzw.js} +5 -4
- package/dist/cli/chunk-q1wwrxzw.js.map +10 -0
- package/dist/cli/{chunk-ave1wcbr.js → chunk-qcyxkj44.js} +1 -1
- package/dist/cli/{chunk-124fvmzq.js → chunk-r5nm9w0c.js} +11183 -8806
- package/dist/cli/{chunk-124fvmzq.js.map → chunk-r5nm9w0c.js.map} +82 -66
- package/dist/cli/{chunk-ckrcm08h.js → chunk-rtvgmg2j.js} +48 -62
- package/dist/cli/{chunk-ckrcm08h.js.map → chunk-rtvgmg2j.js.map} +4 -5
- package/dist/cli/{chunk-297ajdcv.js → chunk-t2h8pwy1.js} +6 -6
- package/dist/cli/{chunk-297ajdcv.js.map → chunk-t2h8pwy1.js.map} +3 -3
- package/dist/cli/{chunk-gxtg6ed2.js → chunk-x60e15st.js} +21 -21
- package/dist/cli/{chunk-gxtg6ed2.js.map → chunk-x60e15st.js.map} +3 -3
- package/dist/cli/{chunk-58bt3hag.js → chunk-x7bh6d9j.js} +4 -4
- package/dist/cli/{chunk-hvcxng5f.js → chunk-ydqzkhjn.js} +6 -6
- package/dist/cli/{chunk-kdpzw38a.js → chunk-yg8ckc3g.js} +95 -7
- package/dist/cli/chunk-yg8ckc3g.js.map +11 -0
- package/dist/cli/{chunk-0pmb4tr4.js → chunk-zxd5jrgx.js} +1205 -222
- package/dist/cli/chunk-zxd5jrgx.js.map +44 -0
- package/dist/cli/index.js +78 -42
- package/dist/cli/index.js.map +7 -6
- package/dist/types/ai/changelog-components.d.ts +18 -0
- package/dist/types/ai/changelog-markdown.d.ts +12 -0
- package/dist/types/ai/openapi-components.d.ts +7 -7
- package/dist/types/ai/operation-details.d.ts +39 -0
- package/dist/types/ai/relative-links.d.ts +3 -1
- package/dist/types/ai/serializers.d.ts +6 -4
- package/dist/types/analytics/head.d.ts +4 -2
- package/dist/types/analytics/script.d.ts +8 -2
- package/dist/types/components/content/youtube.d.ts +20 -0
- package/dist/types/components/layout/nav-utils.d.ts +8 -0
- package/dist/types/components/openapi/example-panels.d.ts +33 -0
- package/dist/types/components/openapi/helpers.d.ts +53 -11
- package/dist/types/components/openapi/snippets.d.ts +7 -1
- package/dist/types/core/alert-diagnostics.d.ts +10 -0
- package/dist/types/core/builtin-tags.d.ts +16 -0
- package/dist/types/core/changelog-list.d.ts +48 -0
- package/dist/types/core/closest-match.d.ts +6 -0
- package/dist/types/core/code-fence-diagnostics.d.ts +18 -0
- package/dist/types/core/code-fences.d.ts +8 -1
- package/dist/types/core/config-input.d.ts +38 -6
- package/dist/types/core/content-assets.d.ts +16 -18
- package/dist/types/core/data.d.ts +6 -2
- package/dist/types/core/diagnostics.d.ts +14 -0
- package/dist/types/core/directive-diagnostics.d.ts +22 -8
- package/dist/types/core/former-routes.d.ts +14 -0
- package/dist/types/core/github.d.ts +5 -4
- package/dist/types/core/heading-markers.d.ts +65 -2
- package/dist/types/core/hidden-pages.d.ts +3 -0
- package/dist/types/core/includes.d.ts +23 -0
- package/dist/types/core/last-modified.d.ts +18 -6
- package/dist/types/core/links.d.ts +42 -2
- package/dist/types/core/load-module.d.ts +19 -4
- package/dist/types/core/manifest.d.ts +14 -1
- package/dist/types/core/markdown-mirrors.d.ts +22 -0
- package/dist/types/core/mcp-clients.d.ts +47 -0
- package/dist/types/core/mdx-elements.d.ts +32 -0
- package/dist/types/core/mdx-syntax.d.ts +100 -0
- package/dist/types/core/meta-diagnostics.d.ts +7 -0
- package/dist/types/core/meta.d.ts +32 -5
- package/dist/types/core/nav-diagnostics.d.ts +16 -2
- package/dist/types/core/navigation.d.ts +13 -0
- package/dist/types/core/ordering-prefix.d.ts +6 -0
- package/dist/types/core/pinned-ids.d.ts +23 -0
- package/dist/types/core/project-graph.d.ts +9 -1
- package/dist/types/core/redirect-patterns.d.ts +18 -0
- package/dist/types/core/relative-files.d.ts +31 -0
- package/dist/types/core/schema.d.ts +322 -11
- package/dist/types/core/sources/normalize.d.ts +101 -9
- package/dist/types/core/sources/types.d.ts +16 -0
- package/dist/types/core/static-files.d.ts +10 -0
- package/dist/types/core/static-host.d.ts +42 -0
- package/dist/types/core/svg-images.d.ts +26 -0
- package/dist/types/core/syntax-diagnostics.d.ts +14 -0
- package/dist/types/core/types.d.ts +42 -1
- package/dist/types/deploy/generated-files.d.ts +41 -0
- package/dist/types/deploy/redirects.d.ts +21 -7
- package/dist/types/markdown/code-title.d.ts +9 -5
- package/dist/types/markdown/directives.d.ts +8 -0
- package/dist/types/markdown/fence-language.d.ts +51 -0
- package/dist/types/markdown/fence-meta.d.ts +5 -0
- package/dist/types/markdown/github-alerts.d.ts +35 -0
- package/dist/types/openapi/asyncapi.d.ts +6 -5
- package/dist/types/openapi/checks.d.ts +10 -5
- package/dist/types/openapi/model.d.ts +55 -8
- package/dist/types/openapi/parse.d.ts +4 -1
- package/dist/types/ratelimit/index.d.ts +2 -0
- package/dist/types/ratelimit/memory.d.ts +1 -1
- package/dist/types/ratelimit/schema.d.ts +40 -0
- package/dist/types/ratelimit/unkey.d.ts +48 -0
- package/dist/types/sources/filesystem.d.ts +14 -4
- package/dist/types/sources/mdx-remote.d.ts +6 -3
- package/dist/types/sources/registry.d.ts +3 -3
- package/dist/types/theme/color.d.ts +33 -0
- package/dist/types/theme/palette.d.ts +122 -0
- package/docs/01-quickstart.mdx +1 -1
- package/docs/02-deployment.mdx +24 -8
- package/docs/04-migrating.mdx +16 -4
- package/docs/advanced/changelog.mdx +27 -1
- package/docs/advanced/skills.mdx +1 -1
- package/docs/cli/audit.mdx +1 -1
- package/docs/cli/doctor.mdx +2 -2
- package/docs/cli/evals.mdx +1 -1
- package/docs/cli/index.mdx +4 -2
- package/docs/cli/validate.mdx +10 -7
- package/docs/configuration/analytics.mdx +2 -0
- package/docs/configuration/customization.mdx +3 -1
- package/docs/configuration/index.mdx +7 -6
- package/docs/configuration/rate-limiting.mdx +20 -1
- package/docs/configuration/theming.mdx +5 -1
- package/docs/content/components.mdx +26 -6
- package/docs/content/frontmatter.mdx +1 -1
- package/docs/content/i18n.mdx +1 -1
- package/docs/content/includes.mdx +6 -2
- package/docs/content/index.mdx +11 -1
- package/docs/content/islands.mdx +2 -0
- package/docs/content/meta.mdx +9 -3
- package/docs/content/navigation.mdx +14 -6
- package/docs/content/sources/obsidian.mdx +1 -1
- package/docs/content/sources/remote-mdx.mdx +3 -1
- package/docs/content/syntax.mdx +76 -8
- package/docs/content/variables.mdx +3 -1
- package/docs/discoverability/agent-discovery.mdx +1 -1
- package/docs/discoverability/json-api.mdx +1 -1
- package/docs/discoverability/llms-txt.mdx +1 -1
- package/docs/discoverability/markdown.mdx +2 -2
- package/docs/discoverability/mcp.mdx +40 -8
- package/docs/discoverability/open-graph.mdx +1 -1
- package/docs/discoverability/sitemap-and-robots.mdx +1 -1
- package/docs/references/graphql.mdx +2 -0
- package/docs/references/openapi.mdx +45 -7
- package/package.json +4 -4
- package/skills/blume/SKILL.md +2 -2
- package/skills/blume-migrate/SKILL.md +51 -29
- package/skills/blume-migrate/references/docsify.md +262 -0
- package/skills/blume-migrate/references/docus.md +298 -0
- package/skills/blume-migrate/references/docusaurus.md +5 -5
- package/skills/blume-migrate/references/fern.md +327 -0
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/gitbook.md +267 -0
- package/skills/blume-migrate/references/github-wiki.md +259 -0
- package/skills/blume-migrate/references/jekyll.md +253 -0
- package/skills/blume-migrate/references/mdbook.md +256 -0
- package/skills/blume-migrate/references/mintlify.md +5 -5
- package/skills/blume-migrate/references/mkdocs.md +236 -0
- package/skills/blume-migrate/references/monorepo.md +20 -8
- package/skills/blume-migrate/references/nextra.md +5 -5
- package/skills/blume-migrate/references/readme.md +257 -0
- package/skills/blume-migrate/references/redocly.md +198 -0
- package/skills/blume-migrate/references/starlight.md +3 -3
- package/skills/blume-migrate/references/vitepress.md +204 -0
- package/skills/blume-migrate/references/vuepress.md +271 -0
- package/skills/blume-migrate/scripts/docsify-codemod.mjs +2387 -0
- package/skills/blume-migrate/scripts/docus-codemod.mjs +2542 -0
- package/skills/blume-migrate/scripts/fern-codemod.mjs +2633 -0
- package/skills/blume-migrate/scripts/github-wiki-codemod.mjs +2808 -0
- package/skills/blume-migrate/scripts/include-excerpts.mjs +649 -0
- package/skills/blume-migrate/scripts/jekyll-codemod.mjs +3649 -0
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +17 -13
- package/skills/blume-migrate/scripts/mkdocs-codemod.mjs +2526 -0
- package/skills/blume-migrate/scripts/operation-routes.mjs +508 -0
- package/skills/blume-migrate/scripts/pin-heading-ids.mjs +1049 -0
- package/skills/blume-migrate/scripts/readme-codemod.mjs +4139 -0
- package/skills/blume-migrate/scripts/vitepress-codemod.mjs +1511 -0
- package/src/ai/changelog-components.ts +24 -0
- package/src/ai/changelog-markdown.ts +45 -41
- package/src/ai/component-markdown.ts +22 -9
- package/src/ai/llms.ts +36 -5
- package/src/ai/markdown.ts +2 -2
- package/src/ai/openapi-components.ts +25 -9
- package/src/ai/operation-details.ts +208 -0
- package/src/ai/relative-links.ts +48 -8
- package/src/ai/serializers.ts +7 -6
- package/src/ai/site-skill.ts +6 -2
- package/src/analytics/head.ts +11 -5
- package/src/analytics/script.ts +13 -3
- package/src/astro/generate.ts +47 -11
- package/src/astro/index.ts +1 -0
- package/src/astro/integration.ts +27 -1
- package/src/astro/mdx-source-errors.ts +46 -0
- package/src/astro/templates.ts +93 -189
- package/src/audit/checks/redirects.ts +5 -1
- package/src/audit/redirects.ts +36 -19
- package/src/audit/report.ts +22 -9
- package/src/audit/run.ts +12 -28
- package/src/audit/terms.ts +23 -0
- package/src/audit/url.ts +2 -2
- package/src/cli/build-failure.ts +256 -7
- package/src/cli/command-meta.ts +1 -1
- package/src/cli/commands/audit.ts +1 -1
- package/src/cli/commands/build.ts +12 -3
- package/src/cli/commands/check.ts +13 -2
- package/src/cli/commands/dev.ts +1 -1
- package/src/cli/commands/doctor.ts +4 -2
- package/src/cli/commands/init.ts +3 -3
- package/src/cli/commands/preview.ts +17 -1
- package/src/cli/commands/validate.ts +22 -10
- package/src/cli/prepare.ts +1 -1
- package/src/cli/preview-pages.ts +161 -0
- package/src/cli/required-secrets.ts +0 -1
- package/src/cli/unknown-flags.ts +1 -42
- package/src/components/code-copy.ts +51 -0
- package/src/components/code-language.ts +75 -0
- package/src/components/content/AccordionItem.astro +16 -1
- package/src/components/content/Callout.astro +11 -1
- package/src/components/content/Changelog.astro +189 -0
- package/src/components/content/CodeBlock.astro +8 -11
- package/src/components/content/Tabs.astro +16 -2
- package/src/components/content/YouTube.astro +6 -4
- package/src/components/content/code-block.ts +33 -0
- package/src/components/content/content-strings.ts +5 -1
- package/src/components/content/inline-markdown.ts +35 -8
- package/src/components/content/youtube.ts +49 -7
- package/src/components/layout/Analytics.astro +5 -1
- package/src/components/layout/NavTree.astro +8 -3
- package/src/components/layout/PageActions.astro +81 -23
- package/src/components/layout/RootLayout.astro +35 -32
- package/src/components/layout/SiteFooter.astro +31 -8
- package/src/components/layout/nav-utils.ts +14 -0
- package/src/components/layout/search/pagefind.ts +2 -1
- package/src/components/openapi/Operation.astro +4 -0
- package/src/components/openapi/PanelTabs.astro +9 -3
- package/src/components/openapi/RequestBody.astro +42 -8
- package/src/components/openapi/RequestPanel.astro +34 -53
- package/src/components/openapi/example-panels.ts +110 -0
- package/src/components/openapi/helpers.ts +195 -20
- package/src/components/openapi/operation-model.ts +63 -26
- package/src/components/openapi/request.ts +13 -0
- package/src/components/openapi/snippets.ts +14 -2
- package/src/core/alert-diagnostics.ts +89 -0
- package/src/core/builtin-tags.ts +76 -0
- package/src/core/changelog-list.ts +87 -0
- package/src/core/closest-match.ts +41 -0
- package/src/core/code-fence-diagnostics.ts +267 -0
- package/src/core/code-fences.ts +43 -7
- package/src/core/component-diagnostics.ts +65 -12
- package/src/core/config-input.ts +39 -5
- package/src/core/config.ts +46 -1
- package/src/core/content-assets.ts +64 -144
- package/src/core/data.ts +10 -3
- package/src/core/diagnostics.ts +36 -3
- package/src/core/directive-diagnostics.ts +265 -47
- package/src/core/former-routes.ts +46 -0
- package/src/core/git-ignored.ts +53 -0
- package/src/core/github.ts +5 -4
- package/src/core/heading-markers.ts +156 -2
- package/src/core/hidden-pages.ts +64 -0
- package/src/core/includes.ts +181 -41
- package/src/core/last-modified.ts +47 -10
- package/src/core/links.ts +438 -83
- package/src/core/load-module.ts +98 -9
- package/src/core/manifest.ts +12 -9
- package/src/core/markdown-mirrors.ts +52 -0
- package/src/core/mcp-clients.ts +87 -0
- package/src/core/mdx-elements.ts +153 -0
- package/src/core/mdx-syntax.ts +377 -0
- package/src/core/meta-diagnostics.ts +134 -0
- package/src/core/meta.ts +154 -55
- package/src/core/nav-diagnostics.ts +41 -4
- package/src/core/navigation.ts +70 -10
- package/src/core/ordering-prefix.ts +22 -2
- package/src/core/pinned-ids.ts +141 -0
- package/src/core/project-graph.ts +221 -29
- package/src/core/redirect-patterns.ts +41 -0
- package/src/core/relative-files.ts +145 -0
- package/src/core/schema.ts +110 -6
- package/src/core/sources/mdx-remote.ts +75 -14
- package/src/core/sources/normalize.ts +885 -179
- package/src/core/sources/notion.ts +5 -4
- package/src/core/sources/obsidian.ts +2 -5
- package/src/core/sources/types.ts +17 -0
- package/src/core/static-files.ts +40 -0
- package/src/core/static-host.ts +125 -0
- package/src/core/svg-images.ts +98 -0
- package/src/core/syntax-diagnostics.ts +491 -0
- package/src/core/types.ts +43 -1
- package/src/deploy/artifacts.ts +2 -28
- package/src/deploy/generated-files.ts +128 -0
- package/src/deploy/platforms/vercel.ts +25 -1
- package/src/deploy/redirects.ts +43 -16
- package/src/deploy/sitemap.ts +2 -1
- package/src/markdown/base-links.ts +87 -6
- package/src/markdown/code-title.ts +29 -13
- package/src/markdown/content-assets.ts +210 -0
- package/src/markdown/directives.ts +69 -5
- package/src/markdown/fence-language.ts +106 -0
- package/src/markdown/fence-meta.ts +42 -0
- package/src/markdown/github-alerts.ts +172 -0
- package/src/markdown/heading-anchors.ts +265 -56
- package/src/markdown/include.ts +30 -3
- package/src/markdown/index.ts +145 -40
- package/src/markdown/prompt-text.ts +95 -0
- package/src/markdown/relative-links.ts +37 -2
- package/src/markdown/route-snapshot.ts +22 -12
- package/src/markdown/svg-fallback.ts +51 -0
- package/src/markdown/title-heading.ts +134 -0
- package/src/migrate/migrate.ts +127 -2
- package/src/og/card.ts +14 -4
- package/src/openapi/asyncapi.ts +14 -6
- package/src/openapi/checks.ts +160 -15
- package/src/openapi/model.ts +172 -33
- package/src/openapi/parse.ts +13 -4
- package/src/openapi/render-mdx.ts +55 -9
- package/src/openapi/source.ts +87 -6
- package/src/ratelimit/index.ts +2 -0
- package/src/ratelimit/memory.ts +1 -1
- package/src/ratelimit/runtime.ts +81 -0
- package/src/ratelimit/schema.ts +2 -0
- package/src/ratelimit/unkey.ts +61 -0
- package/src/registry/eject.ts +0 -1
- package/src/registry/registry.ts +1 -1
- package/src/search/documents.ts +10 -2
- package/src/sources/filesystem.ts +28 -3
- package/src/sources/mdx-remote.ts +7 -15
- package/src/theme/color.ts +14 -0
- package/src/theme/entry.ts +22 -1
- package/src/theme/palette.ts +74 -1
- package/dist/cli/chunk-0pmb4tr4.js.map +0 -35
- package/dist/cli/chunk-0w6hs479.js.map +0 -10
- package/dist/cli/chunk-150jk7km.js +0 -52
- package/dist/cli/chunk-150jk7km.js.map +0 -10
- package/dist/cli/chunk-36bxs9c7.js.map +0 -10
- package/dist/cli/chunk-53jqw8z0.js +0 -89
- package/dist/cli/chunk-53jqw8z0.js.map +0 -10
- package/dist/cli/chunk-60hz265r.js.map +0 -10
- package/dist/cli/chunk-desvm72z.js.map +0 -14
- package/dist/cli/chunk-dpy8qdjf.js.map +0 -17
- package/dist/cli/chunk-es8h0v3j.js +0 -441
- package/dist/cli/chunk-es8h0v3j.js.map +0 -11
- package/dist/cli/chunk-kdpzw38a.js.map +0 -11
- package/dist/cli/chunk-nbyvgnnm.js.map +0 -36
- package/dist/cli/chunk-s0bdnc7v.js.map +0 -10
- package/dist/cli/chunk-twy7psdz.js.map +0 -10
- package/dist/cli/chunk-ydp3065p.js +0 -64
- package/dist/cli/chunk-ydp3065p.js.map +0 -10
- /package/dist/cli/{chunk-y4msrwm9.js.map → chunk-080mfch6.js.map} +0 -0
- /package/dist/cli/{chunk-9qzgg6mj.js.map → chunk-34wap3ed.js.map} +0 -0
- /package/dist/cli/{chunk-1f882900.js.map → chunk-c5bjxq8v.js.map} +0 -0
- /package/dist/cli/{chunk-bxwhtvw8.js.map → chunk-f260jdrn.js.map} +0 -0
- /package/dist/cli/{chunk-74wfhv79.js.map → chunk-fnxgtjeq.js.map} +0 -0
- /package/dist/cli/{chunk-dhwtqnnd.js.map → chunk-gxhcf2hs.js.map} +0 -0
- /package/dist/cli/{chunk-tfycddbt.js.map → chunk-h0qwdbem.js.map} +0 -0
- /package/dist/cli/{chunk-j1x92mx9.js.map → chunk-j4nfgn2j.js.map} +0 -0
- /package/dist/cli/{chunk-ave1wcbr.js.map → chunk-qcyxkj44.js.map} +0 -0
- /package/dist/cli/{chunk-58bt3hag.js.map → chunk-x7bh6d9j.js.map} +0 -0
- /package/dist/cli/{chunk-hvcxng5f.js.map → chunk-ydqzkhjn.js.map} +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# VitePress → Blume
|
|
2
|
+
|
|
3
|
+
VitePress is a Vue/Vite static site generator. Its config is a module in `.vitepress/`, navigation is **declared in `themeConfig.sidebar`**, every `.md` page compiles as a **Vue single-file component** (so it can hold Vue components, `{{ }}`, and `<script setup>`), and its Markdown is markdown-it plus VitePress plugins. Watch for five traps:
|
|
4
|
+
|
|
5
|
+
- **Containers are written `::: tip`, with a space.** Blume renders that as literal text, and warns (`BLUME_DIRECTIVE_SPACED_NAME`) only for a callout name in `.mdx`. Inside an open `:::` container, the same line closes the container and its text is dropped (`BLUME_DIRECTIVE_CLOSING_TEXT`). Directives are also MDX-only.
|
|
6
|
+
- **Every page is `.md`, but most need to be `.mdx`.** A page with a callout, component, or math must be renamed, and MDX is stricter than Vue templates.
|
|
7
|
+
- **URLs end in `.html` by default** (`cleanUrls: false`), so every page needs a redirect.
|
|
8
|
+
- **The heading is the body `# H1`, not frontmatter.**
|
|
9
|
+
- **Pages missing from the sidebar are hidden in VitePress.** In Blume they appear unless you hide them.
|
|
10
|
+
|
|
11
|
+
Scope: VitePress 1.x. Notes marked **2.0** cover `2.0.0-alpha.*`.
|
|
12
|
+
|
|
13
|
+
## Detect
|
|
14
|
+
|
|
15
|
+
- **A `.vitepress/` directory** holding `config.{js,ts,mjs,mts}` (or `config/index.*`), usually `docs/.vitepress/`. The directory that holds `.vitepress/` is the VitePress **project root**: the argument to `vitepress dev <dir>` in the scripts.
|
|
16
|
+
- **A `vitepress` dependency**, often only in the docs package's `package.json`.
|
|
17
|
+
- **Not VuePress**, which uses `.vuepress/` and `vuepress`/`@vuepress/*` deps (`references/vuepress.md`).
|
|
18
|
+
|
|
19
|
+
**Where the Blume project goes.** VitePress has a project root, a `srcDir` (the pages, default `.`), and a public directory that is always `<srcDir>/public`. Blume serves `public/` from the directory holding `blume.config.ts`. Two layouts are common:
|
|
20
|
+
|
|
21
|
+
- The scripts run `vitepress dev docs` from the repo root. Put `blume.config.ts` at the repo root; the default `content.root: "docs"` matches (append `srcDir` if one is set). Move `docs/public/` to `public/`.
|
|
22
|
+
- `docs/package.json` runs `vitepress dev`. Put `blume.config.ts` in `docs/`, set `content.root: "."`, and scope `include`/`exclude` (`references/monorepo.md` §1). `public/` stays put, but exclude it (VitePress sites keep `.md` there behind `srcExclude`), along with `node_modules`.
|
|
23
|
+
|
|
24
|
+
## Run the codemod first
|
|
25
|
+
|
|
26
|
+
Build the source once (`vitepress build <root>`) and copy `.vitepress/dist` outside the repo (`<old build>` below; skip the build if the user already made one): it's your old URL list, the old heading ids, and the record of what the live site rendered, and Teardown deletes `.vitepress/`. Then, on the VitePress source directory (Blume's `content.root`), dry-run and apply the bundled codemod:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
node <skill>/scripts/vitepress-codemod.mjs <srcDir> # report only
|
|
30
|
+
node <skill>/scripts/vitepress-codemod.mjs --write <srcDir> # apply
|
|
31
|
+
node <skill>/scripts/vitepress-codemod.mjs --redirects <old build> # `.html` redirects as JSON
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
It's zero-dependency and idempotent. It converts only where the mapping is exact: containers (paired as markdown-it pairs them, see Markdown extensions), code groups, `details`, GitHub alerts, fence `[label]`s and meta, `<<<` snippet imports and `<!--@include:-->` without regions or line ranges, `.html`/`.md`/trailing-slash links backed by a page, `<Badge type text />`, `{#id}`, `[[toc]]`, and the body H1 → `title`. It renames a page to `.mdx` when the result needs MDX (partials keep their names) and makes its comments and `<br>` MDX-safe. **Everything else is a `REVIEW` line**: frontmatter keys Blume rejects, components, Vue syntax, regions and out-of-root snippets, repaired container structure, unconverted includes (including ones inside code fences, which VitePress spliced). Work through that list with the sections below; it's the migration's to-do list.
|
|
35
|
+
|
|
36
|
+
## Config: `.vitepress/config.*` → `blume.config.ts`
|
|
37
|
+
|
|
38
|
+
Read the whole module and the helpers it imports (sidebars, nav, per-locale configs). For **2.0**, also read directory-level `config.*` files beside the content.
|
|
39
|
+
|
|
40
|
+
| VitePress | Blume |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `title` / `description` | `title` / `description` |
|
|
43
|
+
| `titleTemplate` | drop (report). Blume's `<title>` is `<page> - <site>`; `seo.title` replaces a page's part |
|
|
44
|
+
| `lang` (not `en-US`) on a single-language site | a one-locale `i18n` block (`i18n: { defaultLocale: "fr", locales: [{ code: "fr", label: "Français" }] }`): it sets `<html lang>` and the UI strings, with no switcher or prefix. Use a `code` with a UI pack |
|
|
45
|
+
| `head` | per entry: a known analytics snippet → **that provider's factory** from `blume/analytics` (the gtag loader + `gtag('config', 'G-…')` pair → one `googleAnalytics({ id })`; also GTM, Plausible, …); any other `<script>` → `script()` (`src`, `async`/`defer` → `strategy`, other attrs → `attributes`, inline body → `content`). A `meta` tag → `seo.metatags`, minus the tags Blume writes itself (`description`, `robots`, `og:*`, `twitter:*` card tags; the build names the setting that owns each). `link rel="icon"` → a conventional favicon name in `public/`. Fonts and other tags → drop (report) |
|
|
46
|
+
| `base` (`/repo/`) | `deployment: { base: "/repo" }` |
|
|
47
|
+
| `cleanUrls` | no setting; see "URLs and redirects" |
|
|
48
|
+
| `rewrites` | **move each file to the path its rewrite produced**, so the URL stays put (`slug` only where moving is impossible). VitePress relative links are already written against the rewritten paths |
|
|
49
|
+
| `srcDir` / `srcExclude` | `content.root` / `content.exclude`, which adds to the defaults `**/_*` and `**/.*` |
|
|
50
|
+
| `outDir`, `assetsDir`, `cacheDir`, `ignoreDeadLinks`, `metaChunk`, `mpa` | drop |
|
|
51
|
+
| `appearance` | `'dark'`/`'force-dark'` → `theme.mode: "dark"`; `false` → `"light"`; `true`/`'force-auto'` → omit. Blume always shows the toggle: report a forced mode |
|
|
52
|
+
| `lastUpdated: true` | `lastModified: "git"` |
|
|
53
|
+
| `sitemap.hostname` | `deployment.site`, unless the host is Vercel or Netlify (auto-detected). `sitemap.transformItems` → drop |
|
|
54
|
+
| `markdown.theme` | `markdown.code.theme: { light, dark }`; VitePress's default (`github-light`/`github-dark`) is Blume's, so omit it unless changed |
|
|
55
|
+
| `markdown.lineNumbers: true` | no site-wide switch: add `lineNumbers` per fence, or drop (report) |
|
|
56
|
+
| `markdown.math` | delete `markdown-it-mathjax3`; see Math |
|
|
57
|
+
| `markdown.container` labels, `anchor`, `toc`, `attrs`, `image`, `languages`, `languageAlias`, `headers` | drop (report). A custom `anchor.slugify` changes every anchor |
|
|
58
|
+
| `markdown.config(md)` / `preConfig(md)` with `md.use(…)` | **custom markdown-it plugins: find the syntax each one adds in the content and convert every use** (to Markdown, a directive, or a component); the codemod doesn't know it. Report each plugin |
|
|
59
|
+
| `markdown.codeTransformers` with `@shikijs/vitepress-twoslash` | drop the plugin: ` ```ts twoslash ` works natively |
|
|
60
|
+
| `markdown.externalLinks` | VitePress opens external links in a new tab by default; `markdown.externalLinks: true` keeps that (optional) |
|
|
61
|
+
| `vite`, `vue`, build hooks (`transformHead`, `transformPageData`, `buildEnd`, …) | drop (report what each did). Blume writes canonicals, OG images, `llms.txt`, and the sitemap itself; Astro integrations go in `integrations` |
|
|
62
|
+
| `locales` | `i18n` (see below) |
|
|
63
|
+
|
|
64
|
+
**`themeConfig`** (default theme):
|
|
65
|
+
|
|
66
|
+
| `themeConfig` | Blume |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| `logo` (string, `{ src, alt }`, `{ light, dark, alt }`) | `logo` (string, or `{ image: { light, dark, alt } }`), file in `public/`. A monochrome SVG → `currentColor` and the string form |
|
|
69
|
+
| `siteTitle: false` / a string | `logo: { image: …, text: "" }` / `logo.text` |
|
|
70
|
+
| `nav`, `sidebar` | see the Navigation sections |
|
|
71
|
+
| `socialLinks` | GitHub → `github: { owner, repo }` (it renders in the footer); known platforms → `footer.socials` (`twitter` → `x`; list under `footer` in `docs/configuration/index.mdx`); others, including custom `{ svg }` icons → `footer.links`, or drop (report) |
|
|
72
|
+
| `footer` (`message`, `copyright`) | `copyright` → `footer.copyright`, plain text: strip the tags, decode entities (`©` → `©`); a link inside it loses its URL (report, or add it to `footer.links`); a per-locale `copyright` → a locale map. `message` → drop (report); `footer.links` takes `{ label, href }` |
|
|
73
|
+
| `editLink.pattern` (`…/edit/<branch>/<path>/:path`) | `github: { owner, repo, branch }`. `<path>` leads to the **srcDir**, but Blume builds edit links from the Blume project dir, so `github.dir` is `<path>` minus `content.root` (omit when empty). A non-`github.com` origin → `github.host` |
|
|
74
|
+
| `lastUpdated.formatOptions` | its date fields → `dateFormat`; `text` → drop |
|
|
75
|
+
| `search` | `local` → omit. **Algolia → omit `search`** (Blume's built-in Orama), remove the DocSearch deps, and report the `appId`/`indexName`. That index is almost always DocSearch's, filled by Algolia's crawler, and Blume's sync, given an admin key, replaces the whole index on every build: never point `algolia()` at it. `search: algolia({ appId, apiKey, indexName })` from `blume/search` is for a new index Blume owns, a separate opt-in |
|
|
76
|
+
| `outline` (`2`, `[2, 4]`, `'deep'`, `false`) | `toc` (`{ minHeadingLevel, maxHeadingLevel }`; `'deep'` → 2–6; `false` → `toc: false`), only when declared |
|
|
77
|
+
| `aside`, `docFooter`, the `*Label` strings, `externalLinkIcon`, `carbonAds`, **2.0** `gradedContainers`, theme-package keys | drop. UI strings come from Blume's i18n packs (`i18n.ui`) |
|
|
78
|
+
|
|
79
|
+
## Navigation: `sidebar`
|
|
80
|
+
|
|
81
|
+
VitePress shows only what `sidebar` lists, in that order. Make the file tree match it, carrying labels, order, and collapse into `meta.ts`; reach for `navigation.sidebar` only for shapes files can't express.
|
|
82
|
+
|
|
83
|
+
- **Multiple sidebars** (`{ '/guide/': [...] }`) → one **`navigation.tabs`** entry per key (`{ label, path: "/guide" }`, label from the `nav`). Give each tab folder a `meta.ts` `title` matching its tab label. VitePress sidebars rarely list root pages, so once those are hidden, a root route has no loose pages to show and Blume falls back to the full tree, where an untitled tab folder shows its humanized folder name.
|
|
84
|
+
- **A group whose pages sit flat in one folder** (the nesting exists only in config) → **a `(group)` folder**: `docs/(fundamentals)/controllers.md` still serves `/docs/controllers`, so no URL changes and no redirects. Give it a `meta.ts` (`title`, `pages` in the listed order). A listed page from another folder can join with frontmatter `slug` keeping its old route. **Moving a page one folder deeper breaks its relative links and assets** (`./assets/x.png`, `../other.md`): re-base them, or make them root-absolute.
|
|
85
|
+
- **`collapsed`**: unset → not collapsible (Blume's `flat`); `false` → `display: "group"` + `collapsed: false`; `true` → `display: "group"` + `collapsed: true`, in that folder's `meta.ts`.
|
|
86
|
+
- **A group with its own `link`** → that page becomes the folder's `index` (its URL changes: redirect the old one).
|
|
87
|
+
- **Item `text` that differs from the page's title** → `sidebar.label`. **`base`** → prefix the child links before mapping. External items → `navigation.featured`. `docFooterText`, `rel`, `target` → drop.
|
|
88
|
+
- **Pages no sidebar lists** → `sidebar.hidden: true`. A page listed in two sections, or a cross-section link, can't repeat in filesystem nav: keep one place and report.
|
|
89
|
+
|
|
90
|
+
## Navigation: `nav`
|
|
91
|
+
|
|
92
|
+
- A link to a section a sidebar key backs → a `navigation.tabs` entry. **A dropdown whose items mirror that section's sidebar groups** (a mega-menu) → a plain tab: the sidebar already shows them.
|
|
93
|
+
- A dropdown of pages in one section that isn't the sidebar → a tab with `items` (flat; nested groups flatten).
|
|
94
|
+
- External or utility links → `navigation.actions`; a primary call to action → `navigation.cta`. A version dropdown → drop its version links (report), but move its utility links (Releases, Team, Contributing) to `footer.links` or `navigation.actions`, so pages linked only from there stay reachable.
|
|
95
|
+
- `activeMatch`, `target`, `rel`, `noIcon` → drop.
|
|
96
|
+
|
|
97
|
+
## Titles
|
|
98
|
+
|
|
99
|
+
VitePress takes a page's heading from its first `# H1`; frontmatter `title` only sets `<title>`. Blume renders frontmatter `title` as the H1, so **a body H1 beside a `title` shows twice**; a page with no `title` takes it from the `# H1` that opens its body and shows it once. The codemod moves a plain H1 into `title` and deletes it. It reports two cases: an H1 with inline markup (move it by hand), and a frontmatter `title` that differs from the H1 (make the H1 `title`, keep the old value as `seo.title`). A home page with no H1 takes `hero.name` / `hero.text`.
|
|
100
|
+
|
|
101
|
+
## Markdown extensions
|
|
102
|
+
|
|
103
|
+
VuePress shares the container and fence conventions; its snippet and include syntax differ (see `references/vuepress.md`). **What Blume renders below is MDX-only unless marked `.md` OK.** Of these targets, plain `.md` handles fence titles and meta, `// [!code …]` notations, `{#id}`/`[#id]` anchors, and `<include>`; callouts, components, and math need `.mdx`.
|
|
104
|
+
|
|
105
|
+
**Container pairing.** markdown-it-container scans each container's lines for its closer, so **a bare `:::` closes the outermost open container whose fence is no longer than it, and everything nested in it**. An unclosed container runs to the end of its parent (the page, for a top-level one), and a `:::` with nothing to close shows as text. Real sites have unclosed code groups that swallow the next callout, closers that close two containers, and stray closers. The codemod pairs this way, ends a code group at its last code block when other content follows inside it (a group only holds code), drops stray closers, gives a nested callout's outer fence the extra colon Blume needs, and reports every repair. Check the old build's HTML for literal `:::` to see what the live site already showed broken.
|
|
106
|
+
|
|
107
|
+
| VitePress | Blume |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| `::: tip` / `info` / `warning` / `danger` (spaced) | `:::tip` etc., with **no space**; `::: tip` is never parsed (codemod) |
|
|
110
|
+
| `::: danger STOP` | `:::danger[STOP]`. `:::danger STOP` renders without `STOP`, and `.mdx` warns `BLUME_DIRECTIVE_OPENING_TEXT` (codemod) |
|
|
111
|
+
| `::: note` / `important` / `caution` | **2.0** containers → `:::note`, `:::note`, `:::danger` (`:::warning` with `gradedContainers`). On **1.x** they aren't containers and showed as text; converting changes that: report (codemod) |
|
|
112
|
+
| `::: details Title` (`{open}`) | `<Expandable title="Title">` (`defaultOpen`); untitled → `title="Details"` (codemod) |
|
|
113
|
+
| `> [!NOTE]` `[!TIP]` `[!IMPORTANT]` `[!WARNING]` `[!CAUTION]` (+ `[!INFO]`, `[!DANGER]`) | `:::note` / `tip` / `note` / `warning` / `danger` / `info` / `danger`; text after the marker → `[Title]` (codemod). Unconverted, the five GitHub markers still render as those callouts in `.mdx` (a lazy continuation included); in `.md` they're plain quotes with a literal `[!NOTE]` that warn `BLUME_MD_GITHUB_ALERT` (rename the page to `.mdx`), and `[!INFO]`/`[!DANGER]` are plain quotes in both, with no warning. The codemod leaves lazy-continuation and indented alerts for you |
|
|
114
|
+
| `::: raw`, `::: v-pre` | remove the wrapper lines (codemod) |
|
|
115
|
+
| `::: code-group` + `[label]` fences | `<CodeGroup>`; each block's title is its label (bare token, or `title="Two words"`), else its language as VitePress showed. Blume syncs same-titled tabs page-wide (codemod) |
|
|
116
|
+
| Raw `<div class="tip custom-block">…</div>` (hand-written container markup) | the matching directive |
|
|
117
|
+
| ` ```js{4} ` / ` ```ts:line-numbers ` / ` ```js [file.js] ` | ` ```js {4} ` (Blume reads it glued too) / ` ```ts lineNumbers ` (`=N` start → drop) / ` ```js file.js ` (a bracketed title also shows without its brackets; `.md` OK; codemod) |
|
|
118
|
+
| `// [!code ++]` `--` `focus` `highlight`/`hl` `error` `warning` | same (`.md` OK) |
|
|
119
|
+
| `js-vue` | plain `js`; resolve its `{{ }}` by hand |
|
|
120
|
+
| `<<< @/path/file.ts{2,4} [Label]` (`{lang}`, `:line-numbers`) | `<include meta="Label {2,4}">/path/file.ts</include>` (`lang="…"`, `lineNumbers`); `@` is the srcDir, `/` Blume's content root. In a code group VitePress titles an unlabeled import with its file name. A `.md` target gets `lang="md"`: VitePress showed it as code, Blume would splice it (`.md` OK; codemod) |
|
|
121
|
+
| `<<< file#region` | no region selection in `<include>`: generate the excerpt with `<skill>/scripts/include-excerpts.mjs` (selects `#region` markers; set `"dedent": true`, since VitePress always dedents regions; runs before every build, so the excerpt keeps tracking the source). Where VitePress couldn't find the region it showed the whole file, so check the old build |
|
|
122
|
+
| a snippet outside the content root (`@/../packages/…`) | `BLUME_INCLUDE_OUTSIDE_ROOT` fails the build: copy the file under `_snippets/` and report |
|
|
123
|
+
| `<!--@include: ./part.md-->` | `<include>./part.md</include>` (`.md` OK; codemod). A line range or region → split the partial. VitePress publishes a partial as a page unless `srcExclude` hides it: prefix partials with `_` (excluded by default) and update the paths. A partial is parsed in the including page's format, so one spliced into `.mdx` must be MDX-safe |
|
|
124
|
+
| `[[toc]]` | delete; Blume has the outline rail (codemod) |
|
|
125
|
+
| `:tada:` emoji shortcodes | paste the emoji. A trailing emoji leaves no dash in the id (`## Emoji 🎉` → `#emoji`); the anchor script pins any old id that differs |
|
|
126
|
+
| `## Heading {#id}` | `[#id]` in both formats; a bare `{#id}` fails `.mdx` (codemod) |
|
|
127
|
+
| markdown-it-attrs (`[link](/x){target="_self"}`, `{.class}`) | delete (codemod, for links) |
|
|
128
|
+
| `$…$` / `$$…$$` (`markdown.math`) | `$$…$$` in `.mdx`, block or inline; convert each inline `$…$`, checking it's math |
|
|
129
|
+
| ` ```mermaid ` (`vitepress-plugin-mermaid`) | as written in `.mdx`; delete the plugin |
|
|
130
|
+
| `:::tabs` + `== Label` (`vitepress-plugin-tabs`) | `<Tabs>` of `<Tab title="Label">`, or `<CodeGroup>` when every tab is one fence |
|
|
131
|
+
| Containers a site registers itself (markdown-it-container in `markdown.config`, **2.0** `customContainers`) | read the registration, then map each to a callout, `<Tabs>`, or a component (report). The codemod pairs them as containers and leaves them as written, lengthening an enclosing callout's fence: Blume ends a `:::` callout at a `::: name` line inside it and drops the line |
|
|
132
|
+
|
|
133
|
+
## Vue in Markdown
|
|
134
|
+
|
|
135
|
+
VitePress pages are Vue templates; Blume pages aren't. **In `.mdx` these fail the build**: an HTML comment, `{{ … }}`, a `:prop=` binding, `<script setup>`, an unclosed `<br>`/`<img>`, an `<https://…>` autolink, and `{name}` in prose. **In `.md` they pass through as text or raw HTML** with no error. The codemod reports each.
|
|
136
|
+
|
|
137
|
+
- **`{{ expr }}`, `$frontmatter`, `$params`** → substitute the value; shared values → Blume `variables`; literal braces → inline code. Vue directives on HTML (`v-if`, `v-for`, `v-pre`) → static content.
|
|
138
|
+
- **`<!-- comments -->`** → `{/* … */}` in `.mdx` (the codemod converts one-line ones).
|
|
139
|
+
- **`<script setup>`, `<script>`, `<style>`** → delete; move styles to a root `theme.css`.
|
|
140
|
+
- **`<Badge type text />`** → `<Badge variant>text</Badge>` (`tip`, the default → `accent`; `info` → `default`; `warning`, `danger` as named; **2.0** `note` → `default`, `important` → `accent`, `caution` → `danger`). Blume leaves a badge's text out of the heading's id (`## Title <Badge>beta</Badge>` → `#title`), as VitePress did for a self-closing badge, but VitePress put a badge's children in it (`<Badge type="info">beta</Badge>` → `#title-beta`), so the codemod pins each converted badge heading to its VitePress id (`[#title-beta]`; `[#title]` for a self-closing badge, redundant but harmless). Unconverted in `.mdx`, a `<Badge type text />` renders empty and warns `BLUME_UNKNOWN_PROP`.
|
|
141
|
+
- **Components** (global ones from the theme's `enhanceApp` or a theme package, and imported `.vue` files): decide per component: a Blume component, Markdown, a static `.astro` component in `components.ts`, or the `.vue` file as an island (`islands/`, with `@astrojs/vue vue` installed; `:users="['a']"` → `users={["a"]}`). Components importing from `vitepress` (`useData`, theme parts) can't run outside it. **First check the old build: a component the theme never registered rendered nothing** (`<!---->` in the HTML), so converting it shows content readers never saw. Report it. Data-driven theme components with no source of data (API lists, contributor avatars) → drop, delete headings left empty, and report the lead-in sentences that now point at nothing.
|
|
142
|
+
- **Raw `<img>`/`<figure>` with a relative `src`** → a Markdown image, which is optimized. Left as is, it works: Blume publishes a file a relative `src` names beside the page, unoptimized, and `blume validate` checks it.
|
|
143
|
+
- **`<ClientOnly>`** → drop the wrapper (an island that needs `window` uses `client: "only"`). **`VPTeamMembers`** → a `<CardGroup>` of `<Card>`s, or drop (report).
|
|
144
|
+
- **Data loaders** (`*.data.{js,ts}`) → inline the data, compute it in a custom `.astro` page, or use a content source (report). **Dynamic routes** (`[param].md` + `.paths.*`) → write one page per generated path, then delete the template.
|
|
145
|
+
|
|
146
|
+
## Home page (`layout: home`)
|
|
147
|
+
|
|
148
|
+
- **The site home** → `index.mdx` with `mode: custom` (no title or description rendered, so write the heading): the hero as heading, paragraph, and links; each feature as a `<Card title href icon>` in a `<CardGroup cols={3}>` (an image path or inline `<svg>` icon passes to `icon`; an emoji has no slot). For a designed landing page, `pages/index.astro` on `PageLayout`.
|
|
149
|
+
- **Any other page with `layout: home`** (a team or about page using only the hero) → default doc mode: `hero.name` → `title`, `tagline` → a paragraph.
|
|
150
|
+
- Hero CSS variables and theme-package keys (`testimonial`, `features` styling) → drop (report).
|
|
151
|
+
|
|
152
|
+
## Frontmatter
|
|
153
|
+
|
|
154
|
+
| VitePress | Blume |
|
|
155
|
+
| --- | --- |
|
|
156
|
+
| `title` | see Titles |
|
|
157
|
+
| `description` | pass through |
|
|
158
|
+
| `head` | `meta name=description` → `description` (when the page has none; VitePress didn't emit a page's `head` description beside a frontmatter one); `og:image` → `seo.image`; `link rel=canonical` → `seo.canonical`; `robots` `noindex` → `noindex: true`; `keywords` → drop; anything else → drop (report) |
|
|
159
|
+
| `layout: doc` | remove |
|
|
160
|
+
| `layout: page` | `mode: frame`. **If the page's only content was a component you're dropping, use the default mode** so the title renders |
|
|
161
|
+
| `layout: home` | see Home page |
|
|
162
|
+
| `layout: false` / a custom layout | `mode: custom`, or a custom `.astro` page (report) |
|
|
163
|
+
| `sidebar: false` | `mode: center` |
|
|
164
|
+
| `aside: false` / `outline: false` | `mode: wide`, or drop; `outline` levels, `aside: left` → drop (report) |
|
|
165
|
+
| `prev: false` **and** `next: false` | `pagination: false`; other `prev`/`next` → drop (report) |
|
|
166
|
+
| `lastUpdated: <date>` | `lastModified`; `false` → remove |
|
|
167
|
+
| `titleTemplate`, `editLink`, `footer`, `navbar`, `pageClass`, `markdownStyles`, theme-package keys | drop (report), or declare with `frontmatter.extend` if a component you wrote reads them |
|
|
168
|
+
|
|
169
|
+
## Icons
|
|
170
|
+
|
|
171
|
+
VitePress has no page-icon system. Icons you add (tabs, `meta.ts`, cards) are kebab-case Lucide names; an inline Lucide SVG (`class="lucide lucide-server"`) maps to that name (`server`).
|
|
172
|
+
|
|
173
|
+
## Assets
|
|
174
|
+
|
|
175
|
+
- **`<srcDir>/public/`** → `public/` beside `blume.config.ts`; root-absolute references keep working.
|
|
176
|
+
- **Relative images** work as written and are optimized, **except draw.io/diagrams.net SVG exports**: the `content="<mxfile…>"` attribute on their `<svg>` hides the size Astro reads, so Blume serves the file as it is and warns `BLUME_SVG_UNOPTIMIZED` at the line that embeds it. Strip that attribute to have it optimized.
|
|
177
|
+
- **`.html` files under `public/`** (`/pure.html`) → keep the links.
|
|
178
|
+
|
|
179
|
+
## i18n
|
|
180
|
+
|
|
181
|
+
A `root` locale with others in `fr/`, `zh/` folders matches Blume's `dir` layout: `i18n: { defaultLocale, locales: [{ code, label }] }`, `code` = the folder (not `lang`), `defaultLocale` = the root's language (`en-US` → `en`). Per-locale nav labels → label maps on `navigation.tabs`/`actions`; per-locale sidebars → each locale's `meta.ts`; per-locale `title`/`description` → drop (report). Pin translated headings to their own old ids: translated pages keep their own old anchors, and the anchor script (see URLs and redirects) pairs each page with its own old page, never with the default locale's. With every locale in a folder (`en/` too), move the default up to the root and redirect `/en/…`, or set `hideDefaultLocalePrefix: false`.
|
|
182
|
+
|
|
183
|
+
## URLs and redirects
|
|
184
|
+
|
|
185
|
+
The old URL list is `<old build>/**/*.html` (or the live `sitemap.xml`). Blume serves `/guide/foo` for `guide/foo.md` and `/guide` for `guide/index.md`.
|
|
186
|
+
|
|
187
|
+
- **`cleanUrls: false` (the default): one exact redirect per non-index page,** `{ from: "/guide/foo.html", to: "/guide/foo" }`. `vitepress-codemod.mjs --redirects <old build>` prints them all; paste the array into `redirects`. A pattern can't express a `.html` suffix (`/:path*.html` fails validation).
|
|
188
|
+
- **Don't redirect an index URL** (`/guide/`, `/guide/index.html`, `/index.html`): static hosts serve Blume's `guide/index.html` there already, and `blume dev`/`preview` redirect `/guide/` to `/guide`. `from: "/guide/"` takes over the page (`BLUME_REDIRECT_MATCHES_PAGE`); `from: "/guide/index.html"` builds (no redirect page is written over the page) but is unneeded.
|
|
189
|
+
- **`cleanUrls: true`:** old URLs already match.
|
|
190
|
+
- **A moved route** (undone `rewrites`, a renamed `_`-prefixed page, a numeric prefix Blume strips, a `foo.md` beside `foo/index.md`, which is one route in Blume: `BLUME_DUPLICATE_ROUTE`) → redirect both the `.html` and the clean spelling.
|
|
191
|
+
- **Internal links:** the codemod rewrites `.html`, absolute `.md`, and trailing-slash links that a page backs; it reports the rest. `blume validate` reports each `.html` link left (`BLUME_BROKEN_ASSET`, naming the page's route when one matches). Fix links in config, frontmatter (`hero.actions`), and raw `<a href>` too.
|
|
192
|
+
- **Anchors.** VitePress slugs headings its own way (punctuation runs → one `-`, leading digit → `_`); Blume uses `github-slugger` (punctuation dropped). On a large site hundreds of ids change (`#what-s-new` → `#whats-new`, `#tsed-core` → `#tsedcore`). After the first build, run the anchor script against the old build: `node <skill>/scripts/pin-heading-ids.mjs --old <old build>` (`--write` to apply), then rebuild and rerun it until it reports 0. By default it pins every id that changed; `--only-linked` pins only the ids content links to, for a site where hundreds change, and is a choice to report, since outside deep links to the rest then land at the top of the page. It reads the ids VitePress published, so a custom `markdown.anchor.slugify` is covered too, and it finds each old page at its own route, so add `--map` only for pages that moved. A `NOTE` names a heading it couldn't pin: pin it by hand (`## What's new [#what-s-new]`) if the heading still exists. A pin **replaces** the generated id, so run `blume validate --strict` after: any `BLUME_BROKEN_ANCHOR` left was already dead on the old site (retarget it or drop the fragment, and report it).
|
|
193
|
+
- **Verify** in `dist/`: every old URL is either a built page (`dist/<route>/index.html`) or a `from` in `dist/_redirects` / `dist/vercel.json` whose target is a built page. Static builds also write a meta-refresh page at `dist/<route>.html/index.html`. `blume preview` serves both, applies the redirects as the host files do, and redirects `/<route>/` to `/<route>`, so you can click through old URLs there. On Netlify, set `deployment: netlify({ output: "static" })`: only its `_redirects` forces the rules, so a build for no named host gets the meta-refresh page with a 200. How GitHub Pages serves `/<route>.html` is unverified, so check a few old URLs after deploying there.
|
|
194
|
+
|
|
195
|
+
## Teardown
|
|
196
|
+
|
|
197
|
+
- Remove `vitepress`, its plugins (`vitepress-plugin-*`, `@shikijs/vitepress-twoslash`, `markdown-it-*`), the theme package, and `vue` (keep `vue` + `@astrojs/vue` for Vue islands). Delete `.vitepress/` (once its `dist/` is copied out), data loaders, `.paths.*` files, and PostCSS/Tailwind configs that only served the theme. Theme CSS worth keeping → a root `theme.css` against Blume's tokens (`--vp-c-brand-1` → `theme.accent`).
|
|
198
|
+
- **Check the `tsconfig.json` in the Blume project dir**: Blume's build reads it, so drop `.vitepress` includes and make sure `extends` resolves from that dir (install the root workspace first), or delete it if it only served VitePress. An unresolvable `extends` fails the build (`BLUME_TSCONFIG_EXTENDS`, at the line that names it).
|
|
199
|
+
- Repoint `docs:dev`/`docs:build`/`docs:preview` to `blume dev`/`build`/`preview`. Grep the repo for `.vitepress/dist` and `vitepress build`: CI and deploy configs (Pages workflows, publish scripts, `netlify.toml`) must now publish `dist/` and install the docs package's deps. `.gitignore`: `.vitepress/cache`, `.vitepress/dist` → `.blume`, `dist`.
|
|
200
|
+
- A `404.md` → delete (Blume ships a 404; `pages/404.astro` replaces it).
|
|
201
|
+
|
|
202
|
+
## Dropped — report these
|
|
203
|
+
|
|
204
|
+
`titleTemplate`, the footer `message` (and any link inside `copyright`), forced `appearance`, per-page `outline`/`aside`, one-sided `prev`/`next`, page-level toggles (`editLink`, `footer`, `navbar`, `pageClass`), `head` entries beyond meta tags and analytics, build hooks, Vite and custom markdown-it plugins, unsupported social links, line-number offsets and the site-wide switch, snippet regions and include ranges (now split files), copied out-of-root snippets, data-driven and unregistered theme components (and any content they hid), `VPTeamMembers`, data loaders and dynamic routes, hero styling, the DocSearch index (with its credentials), old-site anchors that were already broken (and any left unpinned under `--only-linked`), version-dropdown links, and `::: note`/`important`/`caution` text that 1.x showed literally.
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# VuePress → Blume
|
|
2
|
+
|
|
3
|
+
VuePress is the Vue static site generator that VitePress succeeded. Its config is a module in `.vuepress/`, navigation is **declared in the theme's `sidebar`**, every `.md` page compiles as a **Vue single-file component**, and its Markdown is markdown-it with `::: name` containers. Most of that layer matches VitePress, so **this file covers only what differs, and sends you to a named section of `references/vitepress.md` for the rest. Keep that file open too.** Watch for six traps:
|
|
4
|
+
|
|
5
|
+
- **`README.md` is a folder's index page in VuePress, but an ordinary page in Blume.** `guide/README.md` publishes at `/guide/README`, and the folder URL `/guide` has no page. Rename every `README.md` to `index.md` (or `.mdx`), then fix the links to it (see "URLs and redirects").
|
|
6
|
+
- **Containers are written `::: tip`, with a space.** Blume renders that as literal text, and warns only for a callout name in `.mdx`; inside an open `:::` container the line closes it instead. See vitepress.md § "Markdown extensions".
|
|
7
|
+
- **URLs end in `.html`** (`/guide/getting-started.html`). Every non-index page needs a redirect.
|
|
8
|
+
- **v1 sidebar groups are collapsible unless `collapsable: false`** (note the spelling). That's the opposite of VitePress and of VuePress 2.
|
|
9
|
+
- **A page's title is its frontmatter `title`, falling back to the body `# H1`, and a page often has both, with different text.** See "Titles".
|
|
10
|
+
- **Theme components fail silently.** `<code-group>`, `<code-block>`, and `<router-link>` have hyphenated names, so they pass through as unknown HTML elements, in `.mdx` too. A code group renders every block stacked, and a router link renders with no `href`. Neither `build` nor `validate` reports them.
|
|
11
|
+
|
|
12
|
+
Scope: **VuePress 1** (`vuepress@1.x`, Vue 2, webpack) with the default theme or a theme that `extend`s it, in full. **VuePress 2** (`vuepress@2.0.0-rc.*`, Vue 3, `@vuepress/theme-default` 2.x) is covered in notes marked **v2**. `vuepress-theme-hope` (v2) has its common syntax under "Themes". For any other theme (`vuepress-theme-reco`, `vuepress-theme-plume`, an ejected `.vuepress/theme/`), inventory its components and frontmatter by hand. The v1 mappings that VuePress's own docs exercise were run end to end on them; the rest of v1 (`permalink`, `base`, `vuepress-plugin-tabs`, the blog plugin, …), the **v2** notes, and the hope section come from source and docs and haven't been run.
|
|
13
|
+
|
|
14
|
+
## Detect
|
|
15
|
+
|
|
16
|
+
- **A `.vuepress/` directory** holding `config.{js,ts}`, or v1's `config.yml`/`config.toml`, or v2's `config.mjs`. It's usually `docs/.vuepress/`. **v2** also reads `vuepress.config.{ts,js,mjs}` from the directory the CLI runs in. The directory that holds `.vuepress/` is the **source dir**: the argument to `vuepress dev <dir>` in the `package.json` scripts.
|
|
17
|
+
- **Dependencies:** `vuepress` (both majors), the v2 betas' `vuepress-vite`/`vuepress-webpack`, or `@vuepress/*`, `vuepress-plugin-*`, and `vuepress-theme-*` packages. They're often only in the docs package's own `package.json`.
|
|
18
|
+
- **Which major:** a `vuepress` version of `^1` means v1. A `2.0.0-*` version, `defineUserConfig`, `bundler: viteBundler()`, or `theme: defaultTheme({…})` means v2. A v1 config is CommonJS (`module.exports`) or `defineConfig` from `vuepress/config` (1.9+), with the theme's options under `themeConfig`. A function config (`ctx => ({…})`) may branch on `ctx.isProd`, so read both sides.
|
|
19
|
+
- **Not VitePress.** VitePress uses `.vitepress/` and a `vitepress` dependency (`references/vitepress.md`).
|
|
20
|
+
|
|
21
|
+
**Where the Blume project goes:** `blume.config.ts` goes in the directory the docs scripts run in (the `package.json` holding `vuepress build docs`, which may be a workspace package like `packages/docs`, not the repo root), with `content.root` set to the source dir (the default `docs` usually matches). When the scripts run `vuepress build` inside the source dir itself, use vitepress.md § "Detect"'s second layout. The public directory is `<source dir>/.vuepress/public` (in **v2**, the `public` option). Move it to `public/` beside `blume.config.ts`. Blume's default `exclude` (`**/.*`) already skips `.vuepress/`.
|
|
22
|
+
|
|
23
|
+
## The VitePress codemod
|
|
24
|
+
|
|
25
|
+
vitepress.md's codemod (`<skill>/scripts/vitepress-codemod.mjs`) also reads VuePress 1 pages. Over VuePress's own docs, with `README.md` already renamed to `index.md`, it converted containers, `details`, `v-pre`, comments, `<Badge>`s (pinning their heading anchors to the old ids, which Blume now gives them anyway), `[[toc]]`, glued fence ranges, body H1s, and links that a page backs, and listed much of the rest as `REVIEW` lines. Run it on the source dir **after** the `README.md` renames (before them, links to folder indexes come back as unbacked; it leaves `.vuepress/` alone), then correct what it treats as VitePress:
|
|
26
|
+
|
|
27
|
+
- **Not reported at all:** lowercase and hyphenated tags (`<code-group>`, `<code-block>`, `<router-link>`, `<demo-1>`; `<Foo-Bar/>` is reported as `<Foo>`), `:emoji:` shortcodes, `@flowstart` blocks, `sidebar: auto` (which then fails the build), **v2** `@[code]` imports, and relative `README.md` links, which stay as written. Grep for each, and rewrite the `README.md` links to the folder (see "URLs and redirects").
|
|
28
|
+
- **`<code-group>` and `<code-block>`** aren't converted, and a page with nothing else to convert stays `.md` (VuePress's English `guide/getting-started.md` did). Convert them, and rename the page to `.mdx`. **v2** `::: code-tabs` / `::: tabs` come back as unknown containers to convert by hand.
|
|
29
|
+
- **The v2 betas' `:::: code-group` + `::: code-group-item Title`** is read as VitePress's `::: code-group`: it comes out as an empty `<CodeGroup>` followed by the items, with a removed "stray" closer. Convert those blocks by hand before running it.
|
|
30
|
+
- **v1 badge types** `error`, `warn`, and `yellow` come out as `accent`: map them as "Vue in Markdown" says.
|
|
31
|
+
- **A frontmatter `title` that differs from the H1** is reported for `seo.title`. In VuePress it was the sidebar text, so it goes to `sidebar.label` (see "Titles").
|
|
32
|
+
- **`<<< @/…`** resolves `@` against the source dir, which is wrong when `vuepress` ran elsewhere. Check each import it converts or reports against the `<<<` row below.
|
|
33
|
+
- **`--redirects`** reads only VitePress builds: on a VuePress build it prints `[]`, which doesn't mean no redirects are needed. Use the command in "URLs and redirects".
|
|
34
|
+
|
|
35
|
+
## Config: `.vuepress/config.*` → `blume.config.ts`
|
|
36
|
+
|
|
37
|
+
Read the whole config, including the modules it imports. VuePress sites often keep `nav` and `sidebar` in per-locale files under `.vuepress/config/`.
|
|
38
|
+
|
|
39
|
+
| VuePress | Blume |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `title` / `description` | `title` / `description` |
|
|
42
|
+
| `base` (`/repo/`) | `deployment: { base: "/repo" }` |
|
|
43
|
+
| `head` | same as VitePress `head` (vitepress.md § "Config"); the `[tag, attrs, content]` format is identical. `link rel="apple-touch-icon"` → copy the file to `public/apple-touch-icon.png`, which Blume detects. `manifest` and `mask-icon` links → drop with the PWA |
|
|
44
|
+
| **v2** `lang` | same as VitePress `lang` |
|
|
45
|
+
| `locales` | `i18n` (see "i18n") |
|
|
46
|
+
| `dest`, `temp`, `cache`, `host`, `port`, `open`, `shouldPrefetch`, `shouldPreload`, v1 `devTemplate` / `ssrTemplate`, **v2** `templateDev` / `templateBuild`, `evergreen`, `extraWatchFiles`, `debug` | drop |
|
|
47
|
+
| `patterns` / **v2** `pagePatterns` | `content.include` / `exclude`. v1's default pattern also builds `.vue` files as pages: rebuild each as Markdown or a custom `.astro` page (report) |
|
|
48
|
+
| `permalink` (v1, site-wide) / **v2** `permalinkPattern` | no setting. Give each affected page a `slug` that reproduces its old URL (see "URLs and redirects") |
|
|
49
|
+
| **v2** `public` | the directory to move to `public/` |
|
|
50
|
+
| `theme` | see "Themes" |
|
|
51
|
+
| `markdown.lineNumbers` (v1) | no site-wide switch. Add `lineNumbers` to the fences that need it, or drop it (report) |
|
|
52
|
+
| `markdown.slugify` | a custom slugify changes every anchor. See vitepress.md § "URLs and redirects" |
|
|
53
|
+
| `markdown.anchor`, `markdown.toc`, `markdown.pageSuffix`, `markdown.extractHeaders` / **v2** `markdown.headers` | drop. If `extractHeaders` added `h4`, set `toc: { maxHeadingLevel: 4 }` |
|
|
54
|
+
| `markdown.externalLinks` / **v2** `markdown.links.externalAttrs` | VuePress opens external links in a new tab by default. To keep that, set `markdown.externalLinks: true` (optional) |
|
|
55
|
+
| `markdown.extendMarkdown`, `chainMarkdown`, `markdown.plugins` / **v2** `extendsMarkdown` (also inside local plugins) | custom markdown-it plugins. Find the syntax each adds and convert every use, as in vitepress.md's `markdown.config` row. Report each plugin |
|
|
56
|
+
| **v2** `markdown.importCode.handleImportPath` | aliases for `@[code]` paths. Apply them as you convert those imports |
|
|
57
|
+
| `configureWebpack`, `chainWebpack`, `postcss`, `stylus`, `scss`, `sass`, `less`, `alias`, `define`, **v2** `bundler` | drop (report) |
|
|
58
|
+
|
|
59
|
+
**Theme options** (v1 `themeConfig`; **v2** the `defaultTheme({…})` options):
|
|
60
|
+
|
|
61
|
+
| VuePress | Blume |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `logo` | `logo`. Move the file into `public/`. **v2** `logoDark` → `logo: { image: { light, dark } }`, and `logoAlt` → `alt` |
|
|
64
|
+
| `nav` / **v2** `navbar` | see "Navigation: `nav`". `navbar: false` → drop (report) |
|
|
65
|
+
| `sidebar` | see "Navigation: `sidebar`" |
|
|
66
|
+
| `sidebarDepth`, `displayAllHeaders`, `activeHeaderLinks` | drop. VuePress listed a page's headings in the sidebar; Blume lists them in the outline rail (`h2`–`h3`, set by `toc`) |
|
|
67
|
+
| `repo` (`owner/name` means GitHub) | `github` adds the footer mark **and** an Edit on GitHub action, so set it only where the site had edit links: v1 with `editLinks: true`, **v2** unless `editLink: false`. Otherwise keep just the mark: `navigation.repo: "https://github.com/<owner>/<name>"`. A GitLab or Bitbucket URL → a `navigation.actions` link; edit links drop (report) |
|
|
68
|
+
| `docsRepo` / `docsBranch` / `docsDir` (edit links) | `github: { owner, repo, branch, dir }`, from `docsRepo` when it's set (then point `navigation.repo` at `repo`). `docsBranch` defaults to `master` in v1 and `main` in **v2**, so set `branch` to the real branch. `docsDir` is the repo path to the source dir, so `github.dir` is `docsDir` minus `content.root` (`packages/docs/docs` → `packages/docs`). **v2** `editLinkPattern` → read the path from it the same way |
|
|
69
|
+
| `lastUpdated` | v1 turns the date on when `lastUpdated` (a label or `true`) is set in `themeConfig` **or in any `themeConfig.locales[path]`**: either → `lastModified: "git"`, and the label drops. **v2** shows it unless `lastUpdated: false`; map it only when the config sets it, and report the default otherwise |
|
|
70
|
+
| `nextLinks: false` **and** `prevLinks: false` (v1) | `pagination: false` on every page: there's no site-wide switch. Only one of them → drop (report) |
|
|
71
|
+
| `search: false` | `search: false` |
|
|
72
|
+
| `algolia` (`apiKey`, `indexName`, `appId`), in `themeConfig` or, in v1, any `themeConfig.locales[path]` | omit `search` (Orama) and report the credentials. A v1 `algolia` block is almost always **DocSearch**: Algolia's crawler fills the index (the app is `BH4D9OD16A` when `appId` is missing, and `algoliaOptions.facetFilters` often marks a shared index). Its records aren't Blume's, and Blume's sync, given an admin key, replaces the whole index on every build. Never point `algolia()` at it; a new index of your own is a separate opt-in |
|
|
73
|
+
| **v2** `colorMode: 'dark'` / `'light'` | `theme.mode`. `colorModeSwitch: false` → report: Blume always shows the toggle |
|
|
74
|
+
| **v2** `hostname` | `deployment.site`, unless the target host is Vercel or Netlify |
|
|
75
|
+
| `locales` | see "i18n" |
|
|
76
|
+
| `smoothScroll`, `searchMaxSuggestions`, `searchPlaceholder`, `repoLabel`, `editLinkText`, **v2** `contributors`, `externalLinkIcon`, `home`, `notFound`, `backToHome`, and the other UI labels | drop. A translated UI string → `i18n.ui` |
|
|
77
|
+
|
|
78
|
+
**Plugins** (`plugins`, plus the ones the theme turns on):
|
|
79
|
+
|
|
80
|
+
| VuePress | Blume |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `@vuepress/plugin-search` (v1's built-in search), **v2** `search`, `slimsearch`, `flexsearch`, `orama` | omit: Orama is the default |
|
|
83
|
+
| **v2** `@vuepress/plugin-meilisearch` | omit, and report: Blume has no Meilisearch adapter |
|
|
84
|
+
| **v2** `@vuepress/plugin-docsearch` | as the `algolia` row: omit `search` and report |
|
|
85
|
+
| `@vuepress/plugin-google-analytics` (v1 `{ ga }`, **v2** `{ id }`) | `analytics: [googleAnalytics({ id })]` from `blume/analytics`. A `UA-` id stopped collecting when Google retired Universal Analytics, so ask for the GA4 `G-` id, or drop it (report) |
|
|
86
|
+
| Other analytics plugins | the matching `blume/analytics` adapter, or `script()` |
|
|
87
|
+
| `vuepress-plugin-sitemap`, **v2** `@vuepress/plugin-sitemap` / `plugin-seo` (`hostname`) | `deployment.site` (with the same host rule as above). Blume writes the sitemap, canonicals, and Open Graph tags itself |
|
|
88
|
+
| `@vuepress/plugin-medium-zoom` | omit: Blume content images zoom on click by default |
|
|
89
|
+
| `@vuepress/plugin-back-to-top` | omit: Blume's page actions include "Scroll to top" |
|
|
90
|
+
| `@vuepress/plugin-pwa` | drop (report). Blume has no service worker. The `manifest` `head` link drops with it |
|
|
91
|
+
| `@vuepress/plugin-last-updated` | `lastModified: "git"` |
|
|
92
|
+
| `nprogress`, `active-header-links`, `smooth-scroll`, **v2** `copy-code`, `git` | drop |
|
|
93
|
+
| `@vuepress/plugin-register-components` | see "Vue in Markdown" |
|
|
94
|
+
| `container` (`vuepress-plugin-container`) / **v2** `@vuepress/plugin-markdown-container` | containers the site registers. Read each entry's `type`, `before`, `after`, and `defaultTitle`, then map it as in vitepress.md's last "Markdown extensions" row (report) |
|
|
95
|
+
| **v2** `@vuepress/plugin-redirect` | its `config` map → `redirects`. `redirectFrom` frontmatter → one `redirects` entry per old path, pointing at that page. A page with `redirectTo` → delete it and add a redirect |
|
|
96
|
+
| `@vuepress/plugin-blog`, `vuepress-plugin-blog` | `type: blog` pages plus a hand-written index (see `docs/advanced/blog.mdx`). Tag, category, and pagination pages → drop (report) |
|
|
97
|
+
| Mermaid, math, tabs, flowchart, and include plugins | see "Markdown extensions" |
|
|
98
|
+
|
|
99
|
+
**Styles:** v1's `.vuepress/styles/palette.styl` `$accentColor` (or **v2** `--vp-c-accent` in `.vuepress/styles/index.scss`) → `theme.accent`. Move other rules worth keeping from `index.styl` / `index.scss` to a root `theme.css`, written against Blume's tokens (report).
|
|
100
|
+
|
|
101
|
+
## Navigation: `sidebar`
|
|
102
|
+
|
|
103
|
+
The rules in vitepress.md § "Navigation: `sidebar`" apply: multiple sidebars become tabs, a group whose pages sit flat beside other groups' pages becomes a **`(group)` folder** (`guide/(advanced)/frontmatter.md` still serves `/guide/frontmatter`, so no redirects; list it in the parent `meta.ts` `pages` by its bare name, `advanced`), and pages no sidebar lists need a decision. The item formats differ:
|
|
104
|
+
|
|
105
|
+
- **Multiple sidebars** (`sidebar: { '/guide/': [...], '/': [...] }`, fallback key last) → one `navigation.tabs` entry per non-root key, as in VitePress. Items inside a key are relative to it: `''` is the key's `README.md`, and `'getting-started'` is `/guide/getting-started.html`.
|
|
106
|
+
- **Items** are page paths, with `.md` optional, or `[path, 'Text']`. A `Text` that differs from the page's title → that page's `sidebar.label`.
|
|
107
|
+
- **v1 groups** (`{ title, path, collapsable, sidebarDepth, children, initialOpenGroupIndex }`) → a folder (or `(group)` folder) with a `meta.ts` (`title`, `pages` in order). `path` → the folder's `index` page. `collapsable` unset or `true` → `display: "group"`. Blume's groups then start collapsed except the one holding the current page, as in v1 (which also opened the first group, or `initialOpenGroupIndex`, on a page no group held). When every group collapses, set `navigation.sidebar.display: "group"` once. `collapsable: false` → keep the default `flat`. `sidebarDepth` and `initialOpenGroupIndex` → drop.
|
|
108
|
+
- **v2 groups** (`{ text, link, prefix, collapsible, children }`, where strings are file paths such as `'foo.md'` or `'/bar/README.md'`, resolved against `prefix`) → the same, except `collapsible: true` is the only collapsible case.
|
|
109
|
+
- **`'auto'`** (v1, as a key's value or the whole `sidebar`) and **v2** `'heading'` (the default) showed only the current page's headings. Blume shows the page tree instead, with the headings in the outline rail. Report that the sidebar changed.
|
|
110
|
+
- **Pages reachable only from the navbar** (common: `config/`, `faq/`, `miscellaneous/` with `sidebar: auto`) → give each section a place in the tree: a tab for a top-level navbar link, or a folder for a dropdown group. Use `sidebar.hidden: true` only for pages that were truly unlisted.
|
|
111
|
+
|
|
112
|
+
## Navigation: `nav`
|
|
113
|
+
|
|
114
|
+
Map it as in vitepress.md § "Navigation: `nav`". v1 items are `{ text, link }`, or `{ text, items }` for a dropdown; a dropdown can hold `{ text, items }` subgroups, which flatten. **v2** items are `{ text, link }`, `{ text, children, prefix }`, or a page path string. Strip `.md` and `.html` from internal `link`s, and turn `README.md` into its folder. `ariaLabel`, `target`, `rel`, and `activeMatch` → drop.
|
|
115
|
+
|
|
116
|
+
**A dropdown whose pages span several folders** (VuePress's own "Learn More": `api/`, `faq/`, `miscellaneous/`, and an external changelog) fits no single tab. Make it a tab with `path: "/"` and `items` for the pages (on those routes the sidebar lists the folders no other tab claims, which here are exactly those, though the tab also highlights on the home page), and move its external links to `navigation.actions`. Or, for a few pages, use `navigation.featured`.
|
|
117
|
+
|
|
118
|
+
## Titles
|
|
119
|
+
|
|
120
|
+
VuePress names a page with its frontmatter `title`, falling back to a heading on the page's first line (normally the `# H1`). That name is the sidebar text and the `<title>`, while the H1 still renders as written. v1's `metaTitle` overrides the whole `<title>`. Blume renders frontmatter `title` as the H1. On every page:
|
|
121
|
+
|
|
122
|
+
1. Move the H1 text into `title` and delete the H1 line. Keep only the text of an H1 that carries a link or a `<Badge>`: move the link into the body, and the badge to `sidebar.badge`.
|
|
123
|
+
2. A frontmatter `title` that differs from the H1 → `sidebar.label`, since it was the sidebar text.
|
|
124
|
+
3. `metaTitle` → `seo.title`, minus VuePress's ` | Site` suffix: Blume adds ` - <site title>` itself. A `metaTitle` without that suffix was the whole `<title>`: keep it as written and report that the site name is now appended.
|
|
125
|
+
|
|
126
|
+
A page with no H1 and no `title` took the site title. Give it a real one. **VuePress gave the H1 an id, but Blume's title has none**, so a link to it (`using-a-plugin.html#using-a-plugin`, meaning the top of the page) fails `validate` with `BLUME_BROKEN_ANCHOR`: drop the fragment.
|
|
127
|
+
|
|
128
|
+
## Markdown extensions
|
|
129
|
+
|
|
130
|
+
Everything Blume renders from these is MDX-only unless vitepress.md marks it `.md` OK, so a page that needs a callout or component is renamed to `.mdx`.
|
|
131
|
+
|
|
132
|
+
| VuePress | Blume |
|
|
133
|
+
| --- | --- |
|
|
134
|
+
| `::: tip` / `::: warning` / `::: danger` (v1 default theme). **v2** adds `info`, `note`, `important`, and `caution` | same as VitePress's containers, with the space removed and a title moved into `[Title]`. **v2** `important` → `:::note` (Blume's alias), `caution` → `:::danger`. v1 has no `note` or `info` container: unless a plugin registers one, the live site showed those lines as text, so converting them changes the page (report) |
|
|
135
|
+
| `::: details Title` | same as VitePress: `<Expandable title="Title">`, or `title="Details"` when untitled. VuePress has no `{open}` |
|
|
136
|
+
| `::: v-pre` | same as VitePress's `::: raw` row |
|
|
137
|
+
| `::: slot name` (v1 Markdown slots) | no equivalent. Put the content where the layout showed it, or drop it (a home page's `::: slot footer` → see "Home page") (report) |
|
|
138
|
+
| `<code-group>` + `<code-block title="YARN">` (v1, 1.6+) | `<CodeGroup>` with blank lines inside, each block's `title` becoming its fence's title (` ```bash YARN `, or `title="Two words"`). `active` on a later block → move that block first (Blume opens the first tab), or use `<Tabs defaultTabIndex={n}>` with one fence per `<Tab title>`. Inside a list item, indent `<CodeGroup>`, its fences, and the closing tag to the item's content column, or the list breaks. Unconverted, the blocks render stacked with no warning |
|
|
139
|
+
| `<CodeGroup>` + `<CodeGroupItem title>`, or `:::: code-group` + `::: code-group-item Title` (**v2** betas) | the same. Unconverted in `.mdx`, `CodeGroupItem` fails the build, and the spaced containers show as text |
|
|
140
|
+
| `::: code-tabs#id` + `@tab Label` / `@tab:active Label` (**v2** default theme, hope) | `<CodeGroup>`, each `@tab` label becoming the title of the fence that follows it (VuePress rendered only that first fence). `#id` → drop: Blume already syncs same-titled tabs across the page. `:active` → as for `<code-block active>` |
|
|
141
|
+
| `::: tabs#id` + `@tab Label` (**v2**, hope) | `<Tabs>` of `<Tab title="Label">`. `#id` → `syncKey="id"`, `@tab:active` → `defaultTabIndex={n}` (zero-based), and `@tab Label#value` → keep only `Label` |
|
|
142
|
+
| `:::: tabs` + `::: tab "Label"` (`vuepress-plugin-tabs`, v1) | `<Tabs>` of `<Tab title="Label">` |
|
|
143
|
+
| ` ```js{4} ` | same as VitePress: Blume reads it as written, and the codemod adds the space |
|
|
144
|
+
| **v2** ` ```ts title="config.ts" ` | works as written (`.md` OK) |
|
|
145
|
+
| **v2** `:line-numbers`, `:line-numbers=N`, `:no-line-numbers` | the first two as in VitePress; `:no-line-numbers` → remove. **v2** turns line numbers on for every block by default; Blume has no site-wide switch (report). `:collapsed-lines`, `:v-pre`, `:no-v-pre` → remove |
|
|
146
|
+
| **v2** `// [!code …]` (the `notation*` options) | same as VitePress |
|
|
147
|
+
| `<<< @/path/file.js{2}` / `<<< @/file.js#region` (v1) | `<include>`, mapped as in VitePress's `<<<` rows, but **`@` is the directory `vuepress` ran in, not the source dir.** Running `vuepress build docs` from the repo root makes `@/docs/x.js` → `<include>/x.js</include>`. v1 imports take no `[label]` or `{lang}`. A region, or a file outside the content root → split or copy the file, as VitePress's rows say |
|
|
148
|
+
| **v2** `@[code](./file.js)` / `@[code{3-10} js{2}:no-line-numbers](../file.js)` | `<include lang="js" meta="{2}">../file.js</include>`. Paths are relative to the page, like `<include>`'s. A line range (`{3-10}`) → split the file (report). Unconverted, it renders as `@` plus a link to the file, with no error |
|
|
149
|
+
| **v2** `<!-- @include: ./part.md -->`, with `{start-end}` or `#region` (`@vuepress/plugin-markdown-include`, md-enhance, hope) | same as VitePress's `<!--@include:-->` row. Unconverted in `.md` it stays an HTML comment, so the content disappears silently. In `.mdx`, it fails the build |
|
|
150
|
+
| `[[toc]]`, `:emoji:` | same as VitePress. VuePress left an emoji shortcode out of a heading's anchor (`## Emoji :tada:` → `#emoji`), and Blume's `## Emoji 🎉` is `#emoji` too, so the pasted emoji keeps the id |
|
|
151
|
+
| `@flowstart` … `@flowend` (`vuepress-plugin-flowchart`) | renders as literal text. Redraw it as a ` ```mermaid ` flowchart (`.mdx`) or an image (report) |
|
|
152
|
+
| **v2** `> [!NOTE]` GitHub alerts (with the hint plugin's `alert` on, or in hope) | same as VitePress's alerts row |
|
|
153
|
+
| Math, ` ```mermaid `, markdown-it-attrs (`{#id}`, `{.class}`) | same as VitePress's rows. v1 and v2 core have no `{#id}` or attrs; only plugins (hope's `attrs`) add them |
|
|
154
|
+
|
|
155
|
+
## Vue in Markdown
|
|
156
|
+
|
|
157
|
+
vitepress.md § "Vue in Markdown" applies: the `.mdx` build errors, `{{ }}`, `<script>`/`<style>` blocks, comments, `<ClientOnly>`, directives, and the per-component decision. VuePress adds:
|
|
158
|
+
|
|
159
|
+
- **Globals:** `$page`, `$site`, `$frontmatter`, `$themeConfig`, `$lang`, `$localePath`, `$title`, `$description`, and `$style` (from `<style module>`) → substitute or delete. `$withBase('/img.png')` → the plain root path (``): Blume adds `deployment.base` to internal links and assets.
|
|
160
|
+
- **`<Badge>`** → Blume `<Badge>`, with the text as **children**. v1 `type`: `tip` (the default) or `green` → `accent`; `warning`, `warn`, or `yellow` → `warning`; `error` → `danger`. **v2** `type`s map as in vitepress.md. `vertical` → drop. An unconverted badge renders empty in `.mdx`, which warns `BLUME_UNKNOWN_PROP`, and as nothing in `.md`, with no warning. **Anchors:** VuePress left a badge out of a heading's anchor (`## Custom Containers <Badge text="default theme"/>` → `#custom-containers`), and so does Blume, so the converted heading keeps its id.
|
|
161
|
+
- **`<router-link to="/x.html">`** (v1), `<RouterLink>`, and **v2** `<RouteLink>` → a Markdown link to the route (`[text](/x)`). `<OutboundLink/>` and `<Content/>` → delete.
|
|
162
|
+
- **Global components:** v1 registers every `.vuepress/components/**/*.vue` file globally, named after the path (`Foo/Bar.vue` → `<Foo-Bar/>`, `demo-1.vue` → `<demo-1/>`), plus theme `global-components` and `Vue.component()` calls in `.vuepress/enhanceApp.js`. **v2** registers them through `@vuepress/plugin-register-components` or `.vuepress/client.{js,ts}`. Decide each as in VitePress. A hyphenated tag passes through as an unknown HTML element, so give the Blume component a PascalCase name and rename its tags (`<demo-1/>` → `<Demo1 />`). **v1 components are Vue 2**, but `@astrojs/vue` runs Vue 3, so an island needs a Vue 3 port: functional components, filters, `$listeners`, `.sync`, and `this.$set` all changed (report). A component that reads `$page`, `$site`, `$themeConfig`, or `this.$router` can't run outside VuePress: rewrite it or drop it.
|
|
163
|
+
- **An escaped `\<App>`** (VuePress's `api/node` headings) renders as text in `.mdx`, with no warning, so it can stay as written.
|
|
164
|
+
- **`.vuepress/enhanceApp.js` / v2 `client.{js,ts}`** (Vue plugins, router hooks, global components) → drop, and report what each did. **v2** client-config `layouts` → custom `.astro` pages.
|
|
165
|
+
|
|
166
|
+
## Home page (`home: true`)
|
|
167
|
+
|
|
168
|
+
Rebuild it as in vitepress.md § "Home page (`layout: home`)": `index.mdx` with `mode: custom`, or a designed `pages/index.astro`. It's usually the source dir's `README.md` (or `index.md`). VuePress's keys:
|
|
169
|
+
|
|
170
|
+
- v1: `heroImage`, `heroAlt`, `heroText` (it defaults to the site title, and `null` hides it), `tagline` (it defaults to the site description, and `null` hides it), `actionText` + `actionLink` (one button), `features: [{ title, details }]`, and `footer`. **v2:** `actions: [{ text, link, type }]` replaces the single action, and adds `heroImageDark`, `heroHeight`, and `footerHtml` (which renders `footer` as HTML).
|
|
171
|
+
- `mode: custom` is full-bleed with no padding, so a hero image renders huge and flush left. Wrap the hero in a centered block (`<div style={{ maxWidth: "60rem", margin: "0 auto", padding: "3rem 1.5rem 0", textAlign: "center" }}>`, with blank lines inside so the Markdown renders) and cap the image (`style={{ maxHeight: "280px", margin: "0 auto" }}`). Add `sidebar.hidden: true` so the home page isn't a sidebar row.
|
|
172
|
+
- Features have no icon or link: each becomes a `<Card title>` with `details` as the body, in a `<CardGroup cols={3}>`. Features written as raw HTML in the body (`<div class="features">`) map the same way.
|
|
173
|
+
- `footer` (HTML with **v2** `footerHtml: true`) or a `::: slot footer` is usually a copyright or license line ("MIT Licensed | Copyright © 2018-present …") → `footer.copyright`, plain text: strip the tags, decode entities (`©` → `©`); move its links into `footer.links`, or they lose their URLs (report). A translated home page's `footer` → that locale's entry in a locale map. Other footer content → drop (report). `heroImageDark` → Blume has no light/dark pair for a content image, so keep one (report).
|
|
174
|
+
|
|
175
|
+
## Frontmatter
|
|
176
|
+
|
|
177
|
+
Blume's schema is strict: every key below must be mapped or removed.
|
|
178
|
+
|
|
179
|
+
| VuePress | Blume |
|
|
180
|
+
| --- | --- |
|
|
181
|
+
| `title` / `metaTitle` | see "Titles" |
|
|
182
|
+
| `description` | pass through |
|
|
183
|
+
| `meta` (v1) / **v2** `head` | per entry, as in vitepress.md's frontmatter `head` row |
|
|
184
|
+
| `canonicalUrl` (v1.7.1+) | `seo.canonical` |
|
|
185
|
+
| `lang` | remove: Blume sets `<html lang>` per locale |
|
|
186
|
+
| `permalink` | `slug`, the old path without its leading `/`, trailing `/`, or `.html` (see "URLs and redirects") |
|
|
187
|
+
| `layout` naming a `.vuepress/components` or theme component | `mode: custom`, and rebuild the content, or use a custom `.astro` page (report). `layout: Layout` → remove |
|
|
188
|
+
| `home` and the hero keys | see "Home page" |
|
|
189
|
+
| `sidebar: auto` / **v2** `sidebar: heading` | remove: the outline rail lists the headings |
|
|
190
|
+
| `sidebar: false` | `mode: center` |
|
|
191
|
+
| **v2** `sidebar` as an array (a per-page sidebar) | remove (report) |
|
|
192
|
+
| `sidebarDepth` | remove |
|
|
193
|
+
| `prev` / `next` | same as VitePress |
|
|
194
|
+
| `search: false` (v1) | remove (report): it hid the search box on that page, which stayed searchable |
|
|
195
|
+
| `tags` (v1, extra search terms) | `search.keywords` |
|
|
196
|
+
| **v2** `date` | keep on `type: blog` pages, otherwise remove |
|
|
197
|
+
| **v2** `redirectFrom` / `redirectTo` | `redirects` (see the redirect plugin row) |
|
|
198
|
+
| `navbar`, `pageClass`, `editLink`, **v2** `editLinkPattern`, `lastUpdated`, `contributors`, `externalLinkIcon`, `permalinkPattern`, `routeMeta` | drop (report) |
|
|
199
|
+
| keys a theme reads | see "Themes" |
|
|
200
|
+
|
|
201
|
+
## Themes
|
|
202
|
+
|
|
203
|
+
- **A theme that `extend`s `@vuepress/theme-default`** (v1's `@vuepress/theme-vue`, or a local `.vuepress/theme/index.js` with `extend`) → treat it as the default theme. Layouts it overrides (ads, banners) → drop (report).
|
|
204
|
+
- **An ejected or local theme** (a full `.vuepress/theme/` with `Layout.vue`, `Navbar.vue`, …) → map the `themeConfig` keys it shares with the default theme. Any extra key (a version list inside the sidebar, say) is custom, so read its components to see what it rendered (report).
|
|
205
|
+
- **`vuepress-theme-hope`** (`hopeTheme({…})`, often in `.vuepress/theme.ts`):
|
|
206
|
+
- **Sidebar** `"structure"` builds the tree from files, which Blume does by default. `order` → `sidebar.order`, `index: false` → `sidebar.hidden: true`, and `shortTitle` → `sidebar.label`. Hope sorts positive `order`s first, then unordered pages by title, then negative `order`s (`-1` last), while Blume sorts a negative order first: renumber, or list the folder's order in its `meta.ts` `pages`. A folder `README.md`'s `dir` → that folder's `meta.ts`: `text` → `title`, `icon`, `order`, `collapsible` (on by default) → `display: "group"`, and `expanded: true` → `collapsed: false`. `dir.index: false` (the folder left out of the generated sidebar) → `sidebar.hidden: true` on each of its pages.
|
|
207
|
+
- **Icons** (frontmatter, navbar, sidebar) are FontAwesome or Iconify names → Lucide (SKILL.md "Icons are Lucide").
|
|
208
|
+
- **Markdown** (the theme's `markdown` options, or `plugins.mdEnhance`): `^sup^`, `~sub~`, task lists, and footnotes work as written. `==mark==` → `<mark>…</mark>`. `::: center` / `::: right` → drop the alignment. `!!spoiler!!` → drop. `<VPCard>` → `<Card>`. A ` ```component Name ` fence (YAML or JSON props) → that component with the props as attributes. `<Catalog />` → `directory: "card"` in that folder's `meta.ts`. `<!-- more -->` → delete. Charts (Chart.js, ECharts, Markmap, PlantUML, flowchart), playgrounds, `::: demo`, and slides → no equivalent: a mermaid diagram, an image, or a link (report).
|
|
209
|
+
- **Frontmatter:** `author` and `date` → `authors` and `date` on `type: blog` pages, otherwise drop. `category` and `tag` → drop (report: Blume has no tag pages), or `search.keywords`. `article`, `star`, `sticky`, `cover`, `isOriginal`, `pageInfo`, `breadcrumb`, `toc`, `comment`, `copy`, `footer`, `copyright`, `containerClass`, and any other hope-only key (`license`, `pageview`, `backToTop`, `sitemap`, `feed`, …) → drop. The project home's `highlights` → more cards. `bgImage` and the hero style keys → drop (report).
|
|
210
|
+
|
|
211
|
+
## Icons
|
|
212
|
+
|
|
213
|
+
The default theme has no page icons. Icons you add to tabs, `meta.ts`, cards, or `sidebar.icon` are kebab-case Lucide names. Hope's icons map as above.
|
|
214
|
+
|
|
215
|
+
## Assets
|
|
216
|
+
|
|
217
|
+
- **`.vuepress/public/`** → `public/`. Root-absolute references (`/hero.png`) keep working.
|
|
218
|
+
- **Relative images** (`./img.png`) work as written.
|
|
219
|
+
- **Webpack paths** (v1 `~@alias/img.png`, `~some-package/img.png`, the `@source` alias) → copy the file into the content root or `public/` and link it plainly.
|
|
220
|
+
|
|
221
|
+
## i18n
|
|
222
|
+
|
|
223
|
+
Map it as in vitepress.md § "i18n". VuePress's `locales` keys are paths (`'/zh/'`), so the `code` is the folder (`zh`), not the `lang` (`zh-CN`). The default locale's `lang` (`en-US`) gives `defaultLocale` (`en`). The theme's per-locale options (v1 `themeConfig.locales`, **v2** the theme's `locales`) carry the rest:
|
|
224
|
+
|
|
225
|
+
- `label` (**v2** `selectLanguageName`) → that locale's `label`. `selectText` (**v2** `selectLanguageText`), `ariaLabel`, `editLinkText`, the `lastUpdated` text, `serviceWorker`, and the other UI labels → drop, or `i18n.ui`.
|
|
226
|
+
- `nav` → per-locale label maps on `navigation.tabs` / `actions`.
|
|
227
|
+
- `sidebar` (keyed `'/zh/guide/'`, …) → each locale's own folder `meta.ts` files.
|
|
228
|
+
- A per-locale container title (`defaultTitle: { '/zh/': '提示' }`) → drop: Blume's UI packs (including `zh`) title callouts.
|
|
229
|
+
- A per-locale `title` / `description` → drop; a translated home page can keep its description in frontmatter.
|
|
230
|
+
- **Anchors:** keep each locale's own old ids (`/zh/` pages had Chinese slugs, which zh pages and outside zh links use). The anchor script does this, pairing every page with its own old page. vitepress.md's "Pin translated headings" means exactly that, not pinning to the default locale's ids.
|
|
231
|
+
|
|
232
|
+
## URLs and redirects
|
|
233
|
+
|
|
234
|
+
Follow vitepress.md § "URLs and redirects", treating VuePress like `cleanUrls: false`: one exact redirect per non-index `.html` page, never a redirect from an index URL, both spellings for a moved route, and rewritten internal links. VuePress specifics:
|
|
235
|
+
|
|
236
|
+
- **Build the old site first and keep its output** (`<source>/.vuepress/dist`, or `dest`): it's the URL list and the record of the old anchors. VuePress writes no sitemap unless a plugin adds one. v1 runs on webpack 4, which fails on current Node with `error:0308010C:digital envelope routines::unsupported`: build it with `NODE_OPTIONS=--openssl-legacy-provider`, or under Node 16 (`npx -p node@16 …`).
|
|
237
|
+
- **Redirects:** run this in that output directory and paste the result into `redirects` (the VitePress codemod's `--redirects` reads only VitePress builds):
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
find . -name '*.html' ! -name index.html ! -name 404.html | sed 's#^\.##' | sort \
|
|
241
|
+
| awk '{ to = $0; sub(/\.html$/, "", to); printf " { from: \"%s\", to: \"%s\" },\n", $0, to }'
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
- **`README.md` → `index.md`** keeps the folder URL (`/guide/` is served from `guide/index.html`), so it needs no redirect. Rewrite each link to a `README.md` to its folder (`./README.md` → `./`, `/guide/README.md` → `/guide`). Once the file is renamed, `blume validate` flags the ones you miss.
|
|
245
|
+
- **`permalink` pages** served the permalink, not the file path. Set `slug` to it. A permalink ending in `.html` also needs a redirect from that `.html` URL.
|
|
246
|
+
- **Links:** VuePress authors link to `.md` files, relative or absolute (`/guide/foo.md`; **v2** recommends relative), and to `.html`. Rewrite them as vitepress.md says. Also fix links in `nav`, `sidebar`, `actionLink`, hero `actions`, and raw `<a href>`.
|
|
247
|
+
- **Anchors: pin them with the bundled script.** VuePress slugs headings as VitePress does, so ids change on many pages (115 headings on 32 of 92 pages in VuePress's own docs, counted before Blume left badges and trailing emoji out of its ids). **Duplicate headings number differently:** VuePress's second `## Options` is `#options-2`, Blume's is `#options-1`. After `blume build`, run from the Blume project:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
node <skill>/scripts/pin-heading-ids.mjs --old <old .vuepress/dist> # dry run
|
|
251
|
+
node <skill>/scripts/pin-heading-ids.mjs --old <old .vuepress/dist> --write # apply
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
It pairs each page's headings with the old build's by text and position, translated pages with their own old pages, and appends `[#old-id]` (`{#old-id}` in `.md`) where the ids differ. Rebuild and rerun until it reports 0. A `NOTE` names a heading whose source line it couldn't match, such as one with inline code, a Markdown escape (`\<`), or `--` (19 of the 115 in VuePress's docs): pin those by hand. It also pins the home hero's `#main-title`, which is harmless. On a large site, `--only-linked` pins only the ids something links to.
|
|
255
|
+
|
|
256
|
+
- **`validate` also reports anchors that were already broken.** VuePress never checked fragments (a zh page linking an English id, a renamed section). Point each at the right heading or drop the fragment, and report it.
|
|
257
|
+
- **Hosts:** Netlify (with pretty URLs) and GitHub Pages also answered `/guide/foo` without `.html`, which Blume keeps. On Netlify, a static build for no named host writes unforced `_redirects` rules, so Netlify serves the meta-refresh page instead of a 301: use `deployment: netlify({ output: "static" })` (see Redirects in `docs/02-deployment.mdx`). The GitHub Pages caveat in vitepress.md applies.
|
|
258
|
+
|
|
259
|
+
## Teardown
|
|
260
|
+
|
|
261
|
+
- Remove `vuepress`, `vuepress-vite` / `vuepress-webpack`, `@vuepress/*`, `vuepress-plugin-*`, `vuepress-theme-*`, `vue`, `vue-template-compiler`, `vue-server-renderer`, and any markdown-it, Stylus, Sass, or webpack packages that only served VuePress. Keep `vue` with `@astrojs/vue` if you made Vue islands.
|
|
262
|
+
- Delete `.vuepress/` (config, `config/`, `components/`, `theme/`, `styles/`, `enhanceApp.js` / `client.*`, `dist/`, `.temp/`, `.cache/`) once `public/` has moved.
|
|
263
|
+
- Repoint the scripts (`docs:dev`, `docs:build`) to `blume dev` / `blume build` / `blume preview`, and add `blume`. Remove `NODE_OPTIONS=--openssl-legacy-provider`.
|
|
264
|
+
- **Node:** Blume needs 22.19 or later, and v1 sites often pin an old one (`.nvmrc`, `engines`, CI `node-version: '14'`, Netlify's `NODE_VERSION`). Bump each. When the same CI job also builds or tests other packages (yarn 1 refuses to install a dependency whose `engines` excludes the running Node), the bump reaches them too, so report it.
|
|
265
|
+
- Grep the repo for `.vuepress/dist`, `dest`, and `vuepress build`. Deploy scripts (the VuePress guide's `deploy.sh` pushing `docs/.vuepress/dist` to `gh-pages`), `netlify.toml` publish dirs, and CI workflows must now publish Blume's `dist/`. Settings kept in a host's dashboard (Netlify's publish directory, build command, and `NODE_VERSION`) can't be committed: list them for the user, with a full (not shallow) clone if you set `lastModified: "git"`.
|
|
266
|
+
- `.gitignore`: replace the docs' own entries (`.vuepress/dist`, the old `dest`) with `.blume` and `dist`. Keep entries other packages in the repo still use (`.temp`, `.cache`).
|
|
267
|
+
- A `404.md` → delete it (as in VitePress).
|
|
268
|
+
|
|
269
|
+
## Dropped — report these
|
|
270
|
+
|
|
271
|
+
Everything vitepress.md's list covers that this site used, plus: v1 Markdown slots, `@flowstart` diagrams that weren't redrawn, the PWA and service worker, `sidebarDepth` and heading-only (`auto`) sidebars, `nextLinks` / `prevLinks` when only one was off, v1 `<code-block active>` defaults that couldn't move, Vue 2 components that weren't ported, `enhanceApp` / client-config code, `.vue` pages, `pageClass` and layout components, Stylus/Sass palette overrides, Universal Analytics ids, the DocSearch index, GitLab and Bitbucket edit links, old-site anchors that were already broken, hope-only components and frontmatter, and any `note` / `info` text that v1 showed literally and now renders as a callout.
|