blume-migrate について
blume-migrateは、既存のドキュメントリポジトリをBlumeへ移行するエージェントスキルです。元のフレームワークに合った手順でコンテンツ、ナビゲーション、設定を変換し、削除または近似した要素を報告します。
主な機能
- 01複数のドキュメントフレームワークを判定
- 02フレームワーク別ガイドに沿った変換
- 03設定、ナビゲーション、ページ構成の移行
- 04リンク、アセットパス、リダイレクトの処理
- 05削除または近似した要素の報告
活用シーン
- 01MintlifyやDocusaurusのドキュメントをBlumeへ移行
- 02既存ナビゲーションをBlumeのページ構成へ変換
- 03移行時のフロントマターと内部リンクの修正
- 04直接対応できない機能の把握
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ haydenbleasel/ blume --skill blume-migrateインストール後、Claude Code で/blume-migrateを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/references/docsify.mddocus.mddocusaurus.mdfern.mdfumadocs.mdgitbook.mdgithub-wiki.mdjekyll.mdmdbook.mdmintlify.mdmkdocs.mdmonorepo.mdnextra.mdreadme.mdredocly.mdstarlight.mdvitepress.mdvuepress.mdscripts/docsify-codemod.mjsdocus-codemod.mjsfern-codemod.mjsgithub-wiki-codemod.mjsinclude-excerpts.mjsjekyll-codemod.mjsmintlify-codemod.mjsmkdocs-codemod.mjsoperation-routes.mjspin-heading-ids.mjsreadme-codemod.mjs詳細
Blume への移行
Blume は Astro/Vite 上で動作する Markdown ファーストのドキュメントフレームワークです。Markdown/MDX をフォルダーに配置するだけで、アプリの定型コードなしに、ナビゲーション、検索、テーマ、Open Graph 画像、コンポーネントライブラリを利用できます。フレームワーク自体がテンプレートです。クローンするスターターはありません。プロジェクトが所有するのは、コンテンツと blume.config.ts だけです。
あなたの作業は、ドキュメントのソースリポジトリを Blume の流儀に沿ったプロジェクトへ変換することです。1 対 1 の置き換えではありません。このファイルを読み、ソースフレームワークを特定し、正確な対応関係が記載された該当する references/<framework>.md を開いて、以下の手順を繰り返してください。削除したものや近似したものは、すべて報告してください。
このスキル全体(references/ ファイルを含む)で、<skill> はこの SKILL.md を含むディレクトリの絶対パスを意味します。このファイルを読み込んだ場所を基準に解決してください(例:node_modules/blume/skills/blume-migrate または .claude/skills/blume-migrate)。これは置き換え用のプレースホルダーであり、リテラルなパスではありません。
移行の方針
- 機械的に移植するのではなく、Blume の流儀に沿った形を目指してください。 明示的な
navigation.sidebarを網羅的に記述するより、ファイルシステムからナビゲーションを生成する方法を優先してください。JSX のコールアウトより:::ディレクティブを優先してください。設定で既定値を再記述するより、Blume の既定値を優先してください。 - すべてのフィールドには既定値があり、
{}も有効な設定です。 ソースで 明示的に宣言されている ものだけを対応付けてください。ソースがフレームワークの既定値を使っている場合は、その設定を記述しないでください。 - Blume に相当するものがない装飾要素は削除し、その旨を伝えてください。 ナビゲーションバーの CTA、カスタムテーマ、条件付きリダイレクト、対応付けできないアイコンは、黙って破棄したり、偽装したりせず、ユーザーに報告してください。
- 変換し、保持しないでください。 Blume のページフロントマターのスキーマは 厳密です。不明なキーがあるとビルドエラーになります。ソースにしかないフロントマターのキーは、Blume のキーに対応付けるか削除してください(削除した場合は報告してください)。「おそらく検証されるだろう」と残してはいけません。
移行のワークフロー
- ソースのフレームワークを検出し、対応するリファレンスファイルを読みます。
docs.json/mint.json→ Mintlify(references/mintlify.md)— 設定で宣言されたナビゲーションを最も深く扱います。docusaurus.config.*→ Docusaurus(references/docusaurus.md)。meta.json+fumadocs-*の依存関係(content/docs/以下にコンテンツがある)→ Fumadocs(references/fumadocs.md)。_meta.{js,ts,json}+nextraの依存関係 → Nextra(references/nextra.md)。starlight({…})を呼び出すastro.config.*→ Starlight(references/starlight.md)。.vitepress/config.{js,ts,mjs,mts}(多くの場合docs/.vitepress/以下)、またはvitepress依存関係 → VitePress(references/vitepress.md)。.vuepress/は VuePress です(次の項目を参照)。.vuepress/config.{js,ts,mjs}(v1 ではconfig.yml/config.tomlも使用。多くの場合docs/.vuepress/以下)、vuepress.config.*、またはvuepress依存関係 → VuePress(references/vuepress.md)。共通する Markdown レイヤーについてはreferences/vitepress.mdを基盤にしているため、両方を読みます。docus依存関係(多くの場合、extends: ['docus']を指定したnuxt.config.tsと並んでdocs/package.jsonにあります)、または 1.x の@nuxt-themes/docus→ Docus(references/docus.md)。ページは MDC(Nuxt Content のコンポーネント構文)です。::note…::は Blume のディレクティブではなく、Blume ではテキストとして出力されます(その行でBLUME_MDC_SYNTAXの警告が出ます)。mkdocs.yml/mkdocs.yaml(Zensical のzensical.toml、ProperDocs のproperdocs.ymlも対象)→ MkDocs / Material for MkDocs(references/mkdocs.md):ナビゲーションは設定で宣言され、Python-Markdown 拡張構文(!!!の注意書き、===のタブ、--8<--のスニペット)を使用し、Python の依存関係を使うため、通常package.jsonはありません。最初にnode <skill>/scripts/mkdocs-codemod.mjs --write <content-dir>を実行し、初回ビルド後にpin-heading-ids.mjsを実行します。fern/fern.config.jsonと並んでfern/docs.ymlがある → Fern(references/fern.md)。docs.ymlのないfern/フォルダーは SDK の生成専用です。ドキュメントは別の場所にあります。.gitbook.yaml/.gitbook.yml、gitbook-docs.yaml、または.gitbook/フォルダーと並んでSUMMARY.mdがある → GitBook(references/gitbook.md)。book.json+SUMMARY.mdは旧式の GitBook CLI または HonKit です(同じリファレンス内の独立したセクションを参照)。book.toml+src/SUMMARY.mdは mdBook です(references/mdbook.md)。book.toml(ブックのルート。コードリポジトリでは多くの場合docs/、book/、guide/以下にあり、章は[book] srcで指定された場所にSUMMARY.mdと並びます)→ mdBook(references/mdbook.md)。すべての URL は.htmlで終わり、SUMMARY.mdがナビゲーション全体を定義します。{{#include}}はリポジトリ内の各所からアンカー付きコードを取り込みます。URL 一覧、旧 ID、インクルードで表示されていた内容の唯一の記録となるため、最初に旧ブックをビルドします。sidebars.yaml、またはredocly.yamlと並んでいることが多い@redocly/realm系の依存関係があり、ページで Markdoc の{% … %}タグを使っている → Redocly(references/redocly.md)。GitBook のページも{% … %}タグを使うため、まず GitBook のファイルを確認します。extends、rules、decorators、apisだけを含むredocly.yamlは Redocly CLI の設定であり、ドキュメントサイトではありません。そのまま残し、ほかの手がかりからフレームワークを検出します。docs/、reference/、recipes/、custom_pages/にある_order.yamlファイル(ReadMe の双方向 Git 同期)、またはcategory/parentDoc(あるいはcategory.uri/parent.uri)のフロントマターを持つページと並んで CI ステップでreadmeio/rdmeを実行している(rdmeによるアップロード)→ ReadMe(references/readme.md)。ReadMe では設定、リダイレクト、用語集、変数はリポジトリではなくダッシュボードで管理され、変更履歴はmainブランチにしかありません。index.htmlでwindow.$docsifyを設定している(通常はdocs/以下にあり、_sidebar.mdと並びます)、またはpackage.jsonにdocsify-cliがある → Docsify(references/docsify.md)。まずnode <skill>/scripts/docsify-codemod.mjs --write --snapshot .docsify-old --group-folders <docs-dir>を実行し、初回ビルド後にpin-heading-ids.mjs --old .docsify-old --map docsify-routes.jsonを実行します。既定の URL は#の後ろに配置されるため(/#/page)、サーバー側のリダイレクトでは一致させられません。リファレンスにはクライアント側スクリプトが追加されています。_config.yml(ルートまたはdocs/以下)→ Jekyll(references/jekyll.md)。Just the Docs は_config.ymlまたはGemfileのjust-the-docsで判別します。プロジェクトローカルの bundle で旧サイトを先にビルドします。ナビゲーションはフロントマター(parent/nav_order)で定義され、旧ビルドのサイドバーから再構成します。URL は/または.htmlで終わります。隣に_toc.ymlがある場合は Jekyll ではなく Jupyter Book です。Jekyll のソースディレクトリで最初にnode <skill>/scripts/jekyll-codemod.mjs --old <old build> --write .を実行し、初回ビルド後にpin-heading-ids.mjs --old <old build>を実行します。<repo>.wiki.gitのクローン(ルートにHome.mdがあり、多くの場合_Sidebar.mdと_Footer.mdがあり、[[Page Name]]形式のリンクを使い、設定ファイルがない)→ GitHub Wiki(references/github-wiki.md)。ソース名で判別できるため、検出されないことはありません。旧 URL はリダイレクトできない github.com 上に残るため、リファレンスではredirectsではなく、旧 Wiki 用のルートテーブルとリンクスタブを作成します。まずnode <skill>/scripts/github-wiki-codemod.mjs routes --repo <owner>/<repo> --writeを実行し、wiki-routes.jsonを分類してから、convert --repo <owner>/<repo> --writeを実行します。- 上記のいずれにも該当しない場合 → このファイルの基本的な考え方を直接適用します。フレームワーク固有のリファレンスはないため、手動で棚卸しします。
- ソースフレームワークとは別に、ホストリポジトリも確認します。 pnpm/Turbo ワークスペース、
docs/以外のコンテンツ配置、Vercel デプロイには、それぞれ統合手順が必要です(content.rootのスコープ設定、minimumReleaseAge、ロックファイル、vercel.json、Astro/Vite パッチ)。すべてreferences/monorepo.mdに記載されています。ターゲットが単一パッケージだけの単純なドキュメントフォルダーでない場合は必ず読みます。
- 変更前にリポジトリを棚卸しします。 本文が
<meta http-equiv="refresh">だけのページはリダイレクトであり、ページではありません。その旧 URL からのリダイレクトを追加して、報告します。設定ファイル、コンテンツツリー、ナビゲーション定義、スニペット/パーシャル/インクルード、静的アセット、OpenAPI/AsyncAPI 仕様と GraphQL スキーマ、リダイレクト、i18n ロケール、カスタムコンポーネント、アイコンの使用状況を確認します。宣言されたものと既定値を区別して記録します。旧サイトが誤って公開していたページ(.github/のテンプレート、ドットフォルダー以下のファイル、計画メモ)はコンテンツではありません。対象から除外し、リダイレクトを追加せず、報告に記載します。 blumeのdefineConfigを使ってblume.config.tsを作成します。 宣言済みのフィールドだけをマッピングし(リファレンスのマッピング表を参照)、それ以外はすべて既定値に任せます。最小構成はdefineConfig({ title: "…" })です。- コンテンツを再構成します。
blume.config.tsは、旧ドキュメントビルドを実行するpackage.jsonがあるディレクトリに置きます。これはリポジトリルートではなく、packages/docsのようなワークスペースパッケージの場合があります。content.root(既定値はdocs)を選びます。.md/.mdxが実際に置かれている場所を検出し、docs/フォルダーがあると思い込まないでください。 多くのリポジトリでは、docs/サブフォルダーを作らず、コンテンツをアプリディレクトリ直下(apps/docs/api/、.../getting-started/など)に置いています。その場合はcontent.rootをそのディレクトリに設定し、content.includeを実際のコンテンツフォルダーに絞ります。すべてを走査してしまうcontent.root: "."だけの設定は避けてください(references/monorepo.md§1 を参照)。01-intro.mdxのような数値プレフィックスで順序を指定し、URL セグメントを追加しないグループは(group)/フォルダーにまとめます。ファイルシステム上の順序だけでは不十分な場合に限り、meta.ts(defineMeta)を追加します。ソースがサイドカーファイルでフォルダーごとのナビゲーションをすでに宣言している場合(Fumadocs のmeta.json、Nextra の_meta.*)は、ここに該当します。それぞれをmeta.tsに変換し、タイトル/アイコン/順序/折りたたみ設定を引き継ぎます。ファイル名だけで意図を再現できると期待して、宣言を破棄してはいけません。 ファイルシステムからの推定は、フォルダーごとのナビゲーションが宣言されていない場合の代替手段であり、宣言済みの設定を捨てる理由にはなりません。ソースのナビゲーション設定にだけ存在し、ページがディスク上ではフラットに配置されているグループは(group)/フォルダーにします。これによりサイドバーのグループを追加しつつ、すべての URL を維持でき、リダイレクトは不要です。ページをより深いフォルダーに移すと URL が変わり、相対アセットパスも壊れるためです。ソースのナビゲーションをファイルだけで表現できない場合に限り、明示的なnavigation.sidebarを使用します。タブごとのフォルダーに再構成すると URL が変わります。作業中に旧パスから新パスへの変更をすべて記録し、手順 5 でredirectsに追加します。 - ページを書き換えます。 フロントマターを Blume の厳格なスキーマにマッピングし、コールアウト JSX を
:::ディレクティブに変換します。ディレクティブ(および数式/Mermaid/パッケージインストール用のコードフェンス)は MDX 専用です。これらを必要とする.mdページはすべて.mdxに変更します。 コンポーネントの名前を変更し、スニペット/パーシャルを<include>文に変換するかインライン化します(Blume には import ベースのインクルードがないため、import Snippet from "…"と<Snippet />はどちらか一方に変える必要があります。ソースがファイルの一部(mdBook のANCHOR、VitePress の#region、MkDocs のスニペット行範囲)やコンテンツルート外のファイルを取り込んでいる場合、プロジェクトに<skill>/scripts/include-excerpts.mjsをコピーし、dev、build、validateの前に毎回実行します。プロジェクトがコンパイルするコードを手作業で貼り付けてはいけません。このスクリプトは、見つからないアンカーやリージョンを一度にすべて報告します。ソースに復元されたマーカーがある場合は、古くなっても気づかれない行範囲より優先します)。アセットパスを修正します。内部リンクを新しいルートに書き換えます(OpenAPI/GraphQL の操作リンクも含みます。多くのソースとはスラッグが異なるため、API リファレンスのセクションを参照してください。また、Blume は OpenAPI の説明文をレンダリングして検証するため、その中のリンクも書き換えます。ただし、fromにリダイレクトを指定すると古いリンクが隠れてしまいます。旧サイトのオリジンをハードコードしたリンクはルート相対パスに書き換えます)。手順 4 で移動したルートすべてについてredirectsエントリーを追加します(Docsify のようにハッシュを使うソースでは、redirectsはパスしか認識しないため、リファレンスのクライアント側リダイレクトも必要です)。アイコン名はすべて Lucide に変換します(Blume が対応するのは Lucide のみで、FontAwesome/Tabler は使えません)。本文内で重複する H1 は削除します(titleが H1 をレンダリングするため、本文は##から始めます)。そのアンカーへのリンク(#<h1-slug>)も修正します。アンカーがなくなるため、フラグメントを削除します。blume validate --strictは旧サイトでは検証されていなかったフラグメントも報告します。各フラグメントを修正するか削除し、報告してください。フロントマターにtitleがないページでは、冒頭の# H1がタイトルとして使われ、一度だけ表示されるため、そのままでも構いません。titleに移すのが標準的な書き方です。ソースに手作業で管理された変更履歴があり、リポジトリが GitHub でオープンソースとして公開されている場合は、エントリーを移植する代わりにgithubReleases()ソースに置き換えることを提案します(以下の「変更履歴」を参照)。Mintlify では、まず付属の codemod を実行します。node <skill>/scripts/mintlify-codemod.mjs --write <content-dir>は、アイコンを決定論的に再マッピングし、サポートされていないフロントマターのキーを削除/変更して、残り(不明なアイコン、OpenAPI スタブのフラグなど)を手動対応用に報告します(references/mintlify.mdを参照)。Docus では、まず付属の codemod を実行します。node <skill>/scripts/docus-codemod.mjs --write contentは、remark-mdc と同じ方法で MDC ブロックを対応付け、Nuxt UI の文章用コンポーネント、フェンスラベル、アイコン、フロントマター、.navigation.ymlファイルを変換し、MDX の文章を安全な形にして、すべてのREVIEW項目を一覧表示します(カスタムコンポーネントとランディングページ用コンポーネントはそのまま残ります。ローカルビルドだけでなく実際のサイトと照らし合わせて確認してください。references/docus.mdを参照)。VitePress では、まず付属の codemod を実行します。node <skill>/scripts/vitepress-codemod.mjs --write <srcDir>は、コンテナ(markdown-it と同じようにペアを対応付けます)、コードグループ、アラート、フェンスラベル、<<<のインポートとインクルード、.htmlリンク、バッジ、H1 タイトルを変換し、手作業で対応するREVIEW項目を一覧表示します(references/vitepress.mdを参照)。ソースのコンポーネントを変換する前に、ビルド済みの出力を確認します。テーマに登録されていないコンポーネントは元のサイトでは何もレンダリングしていなかったため(``)、変換すると読者が見ていなかった内容が表示されます。報告してください。mdBook では、ほかの作業より先に{{#…}}ヘルパーをすべて変換します。アンカー付き、行範囲指定、ルート外のコードは生成された抜粋になり、1 行のファイルはvariablesになります。その後、非表示の#行とrust,…フェンス属性を削除し、admonish ブロックを変換します(references/mdbook.mdを参照)。Jekyll では、すべての Kramdown IAL({: .note })と Liquid タグを変換します。.mdでは文字どおりのテキストとして出力されます(Liquid タグにはBLUME_TEMPLATE_TAG、IAL にはBLUME_MD_ATTRIBUTE_LISTの警告が出ます)。.mdxではビルドが失敗します(blume checkは IAL ごとにBLUME_MDX_ATTRIBUTE_LIST、Liquid タグごとにBLUME_MDX_SYNTAXを該当行で示します。インクルードしたパーシャル内にある場合は、そのパーシャル内の行が示されます)。まず付属の codemod を実行します。このスクリプトは、コールアウト IAL、ページ内目次、H1、フロントマター、Markdown インクルード、Liquid のリンクと変数を変換し、Just the Docs のサイドバーをフォルダー、slug、meta.tsに再構成して、リダイレクトと変数をjekyll-migration.jsonに書き込みます(references/jekyll.mdを参照)。GitHub Wiki では、付属の codemod(routes、続けてconvert)を実行します。ページ名ごとに 1 つのフラットなルートからなるルートテーブルを作成し、コード外にある[[…]]リンクをすべて変換します。変換しないと Blume はこれらを文字どおりのテキストとして出力します(ページ名を指すもの、または|を含むものに限りBLUME_WIKILINK_UNSUPPORTEDの警告が出ます。Markdown ページではリンクテキストが先です。[[text|Page]])。Redocly では、Markdoc の{% … %}タグをすべて変換します。Blume はこれらを解析しないため、未変換のタグは.mdでは文字どおりのテキストとして出力され(該当行にBLUME_TEMPLATE_TAGの警告が出ます)、.mdxではビルドが失敗します。VuePress では、最初にすべてのREADME.mdをindexに変更してから、VitePress codemod を実行します(VuePress コンテンツでの制限についてはreferences/vuepress.mdを参照)。次に、ハイフンを含むテーマタグ(<code-group>、<code-block>、<router-link>)を検索します。これらは診断なしで、未知の HTML 要素として.mdxにそのまま出力されます。MkDocs では、変換前にページごとに.mdと.mdxのどちらにするか決めます。MDX は、Python-Markdown では受け入れられる HTML コメント、<https://…>形式の自動リンク、閉じられていない void タグ、{…}属性リストを拒否します(blume checkは各エラーを該当行で示します。MDX が解析できない構文はBLUME_MDX_SYNTAX、後の 2 つはBLUME_MDX_UNCLOSED_ELEMENTとBLUME_MDX_ATTRIBUTE_LISTです)。スニペットのパスはページではなくスニペットのbase_path(既定値は MkDocs の実行場所)を基準に解決されます(references/mkdocs.mdを参照)。Fern では、URL はファイルパスではなくdocs.ymlから決まります。ファイルを移動する前にnode <skill>/scripts/fern-codemod.mjs --sitemap old-urls.txtを実行します(最初はドライラン、その後--write)。初回ビルド後は、そのendpointsステップでoperation-routes.mjsの出力を Fern の旧 API URL に結合し、fern-redirects.jsonに書き込みます。Fern Definition はfern exportで OpenAPI にエクスポートします(references/fern.mdを参照)。GitBook では、各ページをまず旧 URL に配置します(GitBook の URL はファイルツリーではなくSUMMARY.mdに従います)。その後、{% … %}タグをすべて変換します。変換しないタグは.mdでは文字どおりのテキストとして出力され(BLUME_TEMPLATE_TAGの警告が出ます)、.mdxではビルドが失敗します。ReadMe では、まず付属の codemod を実行します。node <skill>/scripts/readme-codemod.mjs --write --site <hub origin> --glossary <saved hub page> .は、各ページをフラットな URL に保ち、コールアウト、doc:/ref:リンク(残っているものはblume validateがBLUME_UNSUPPORTED_LINK_SCHEMEとして示します)、ReadMe コンポーネント、フロントマターを変換し、meta.ts、オーバーレイ、リダイレクトを書き込んで、人手での対応が必要な項目を一覧表示します。初回ビルド後に--routesを実行すると、エンドポイントへのリダイレクトとタグごとの順序が追加されます(references/readme.mdを参照)。貼り付けられたウィジェットの JSX イベントハンドラー(onClick={…})はビルドが成功しても静的ページでは動作しません。BLUME_MDX_EVENT_HANDLERで各箇所が示されるため、ウィジェットをアイランド(islands/)に移すか削除し、報告してください。 package.jsonを更新します。dev/build/startをblume dev/blume build/blume previewに切り替え、旧フレームワークの依存関係を削除して、blumeを追加します。設定ファイルしかないソース(例:docs.jsonだけの Mintlify)にはマニフェストがないため、新たに作成します。pnpm ワークスペースの場合:pnpm-workspace.yaml/.npmrcでminimumReleaseAgeが設定されていたら、新しく公開されたバージョンをインストールできるようにminimumReleaseAgeExcludeにはblumeだけを追加します(ガードを無効にしないでください)。Yarn のnpmMinimalAgeGateも同じように新しいblumeを拒否します。npmPreapprovedPackagesに追加します。必ず同じ変更で、リポジトリ独自のパッケージマネージャーを使ってロックファイルを再生成し(ワークスペースルートからpnpm install、yarn install、npm install、bun installのいずれかを実行します。packageManagerとロックファイル名を確認してください)、package.jsonとともにコミットします。CI とホストはフローズンロックファイルからインストールするため、古いロックファイルがあるとビルド開始前に失敗します。コンテンツルート内に最初の新規ファイル(meta.tsやパーシャル)を作成したら、git check-ignore -v <content root>/meta.tsを実行します。コンテンツルートを対象とするリポジトリの.gitignoreルールがあると、旧ページは追跡されたまま新規ファイルがすべてgit addから除外されるため、ルールを修正するか、新規ファイルごとにgit add -fが必要なことを報告します。Blume には Node 22.19 以降が必要です。同じ変更で.nvmrc/.node-version、engines.node、CI のnode-versionを更新します。pnpm 11 以降では、pnpm-workspace.yamlで許可された場合にのみ、依存パッケージのビルドスクリプトが実行されます。ワークスペースにすでにesbuildが記載されていない限り、allowBuilds: { esbuild: true }(およびblume initが書き込む"@scarf/scarf": false)を追加し、ほかのエントリーは残します。docsパッケージ独自の.gitignoreがある場合はそこに、なければルートの.gitignoreに.blume/、dist/、.env.localを追加します(blume initと同じです。vercel()ビルドは.vercel/を自動で追加します)。アセットを移動する前に、public/を無視する行があれば削除します。blume buildは<project>/distを空にします。 ホストリポジトリがすでにdist/を別の用途(Python wheel、ライブラリのビルドなど)に使っている場合は、Blume プロジェクトをdocs/などの独立したフォルダーに配置します。リポジトリで Prettier を使っている場合は、*.mdのオーバーライド(.prettierrc、.editorconfig)を*.mdxにも適用し、{/* */}コメントを 1 行に保ちます。ページの名前変更または移動後、リポジトリ全体から旧パスを検索します(リリース設定、CI、bot、ignore ファイルも対象です)。Blume プロジェクトディレクトリ内のtsconfig.jsonも確認します。Blume のビルドはこれを読み込むため、ルートワークスペースをインストールして初めて解決されるextendsや、旧フレームワークのフォルダーを対象とするincludeがあるとblume buildは失敗します。先にワークスペースをインストールするか、パスを修正するか、旧フレームワークだけが使っていたファイルであれば削除します(./.nuxt/*をextendsまたはreferencesする Nuxt のtsconfig.jsonはBLUME_TSCONFIG_EXTENDSで失敗し、postinstall: nuxt prepareスクリプトも Nuxt の依存関係とともに削除します)。リポジトリで Ultracite を使っている、またはユーザーがフォーマッターとして使用したい場合: 同梱のassets/[email protected]を含めてpatchedDependenciesに登録しないと、oxfmt フォーマッターが追加した:::ディレクティブを壊します。references/monorepo.md§6 を参照してください。references/monorepo.md§2–3 も参照してください。- ホストリポジトリを接続してデプロイします(複雑なリポジトリの場合)。 ホストのダッシュボードで管理される設定(Netlify の公開ディレクトリ、ビルドコマンド、
NODE_VERSIONなど)はコミットできないため、概要に記載します。.gitignoreではドキュメント専用のエントリーだけを置き換え、ほかのパッケージが使うエントリーは残します。Vercel 上のモノレポでは、ルートを考慮したインストール/ビルド手順とapps/docs/vercel.jsonを作成します。静的ビルドではoutputDirectory: "dist"を指定し、ビルド先が.vercel/outputとなるdeployment: vercel()ではoutputDirectoryを指定しません(Turborepo の出力に.vercel/output/**を追加します)。コミットできない設定(Vercel Root Directory、Node 22、AI_GATEWAY_API_KEYなどのサーバーシークレット)をユーザーに伝えます。ワークスペースで Vite を固定しており、Astro/Vite 内部でblume buildがクラッシュする場合は、pnpm-patch の回避策を適用します。コピーして使用できる手順はすべてreferences/monorepo.md§4–5 にあります。 - 検証します。
blume build(フロントマターのスキーマ、重複ルート、設定を検査します。既定では診断エラーがあると失敗します。--no-strictは絶対に渡さないでください。 ビルドを続行して、不正なフロントマターや解析できない.mdxがあるページを黙って破棄します)とblume validate --strict(内部リンク、見出しアンカー、アセット、リダイレクト先を検査します。リンクチェッカーはbuildではなくvalidateにあります)を実行し、診断結果を修正してから、表示を確認するためにblume devを実行します。最後に、移行したもの、削除したもの、近似したものをまとめて記述します。さらに、理由を添えて、リポジトリ固有に行った編集(pnpm-workspace、vercel.json、設定の glob など)をすべて記載し、Astro パッチや Vercel ダッシュボード設定など、ユーザーに残した手動作業も含めます。
Blume のメンタルモデル
多くのソース、特に Mintlify で最も大きく変わる点は、ナビゲーションが設定ファイルで宣言されるのではなく、ファイルシステムから生成されることです。
ナビゲーションはファイルツリーです
- フォルダーはグループに、ファイルはページになります。 ページのサイドバーラベルはフロントマターの
title、グループのラベルは人が読みやすい形にしたフォルダー名です。 - 順序は優先度の高いものから適用されます: 明示的な
navigation.sidebar(ツリー全体を置き換えます)→ フォルダーのmeta.tsのpages配列 → ページのフロントマターのsidebar.order→ ファイルシステム(indexが最初、その後に01-のような数値のファイル名プレフィックス、最後にアルファベット順)。 meta.tsは1つのフォルダーを調整します(defineMeta({ title, icon, order, collapsed, pages, display, directory }))。pages配列には、スラッグ(数値のプレフィックス、かっこ、拡張子を除去したもの)で子ページを記述します。存在しない名前を指定すると、意図した可能性のあるスラッグとともにBLUME_META_UNKNOWN_PAGEの警告が出るため、そのスラッグを記述してください。省略した子ページは、それぞれのsidebar.order、次にファイルシステムの順序(indexは引き続き最初)に従います。そのため、pagesの一部だけを記述しても問題ありませんが、ソースで完全な順序が指定されている場合は、すべての子ページを記述してください。directoryはツリーの下位に継承されます。カードを表示しないネストされたフォルダーにはdirectory: "none"を設定してください。flatグループ内のページとサブグループを交互に並べたり、どのモードでもサイドバー最上位で交互に並べたりすることはpagesではできません。ソースでそれらが交互に並ぶ場合(mdBook、MkDocs のnavigation.sections)、display: "group"を使ってください。この場合、順序はグループ内で保持されます。トップレベルで移動した項目も明記してください。- サイドバーの表示モード:全体のデフォルトとフォルダーごとの上書きがあります。
blume.config.tsのnavigation.sidebar.displayは"flat"(デフォルト)、"group"(折りたたみ可能)、または"page"(サブパネルへのドリルイン)で、すべてのグループのモードを一度に設定します。フォルダーでは、それぞれのグループのモードを上書きできます。meta.tsのdisplay、またはフォルダーにindexページがある場合はそのページのフロントマターのsidebar.displayを指定します。後者は簡易記法です。優先順位は、インデックスページのフロントマター →meta.ts→ グローバル設定 →flatです。上書きはそのグループだけに適用され、ネストされたサブグループはそれぞれ独自の設定順序に従います。そのため、ソースのカテゴリごとの折りたたみ/ドリルインモードは、フォルダーごとの設定に移行します。サイドバー全体を変更する場合にのみ、グローバルモードを使用してください。明示的なnavigation.sidebarを使用する場合、グループごとに設定できるのは設定項目自体のdisplayフィールドだけです(フロントマター/metaのdisplayは無視され、BLUME_SIDEBAR_DISPLAY_IGNOREDの警告が出ます)。 - 明示的な
navigation.sidebarは、ファイルシステムからの生成全体を置き換えます。 ファイルでは表現できないナビゲーション構造に限り使用してください。項目には、ページのルート文字列、グループ({ label, items })、またはリンク({ label, href })を指定できます。 - 設定で宣言されたネスト構造にディスク上の対応関係がない場合、実体化しないと通知なくフラット化されます。 ソース(Mintlify の
groups、Nextra の_meta、Docusaurus のサイドバーなど)でネストされたグループが宣言されていても、そのページは通常、1つのフォルダー内にフラットに置かれ、グループ分けは設定にのみ存在します。ファイルシステムから生成されるナビゲーションではフラットなフォルダーとして認識され、内側のグループは失われます。ネスト構造を維持するには、まず(group)/フォルダーを使います。ページを<folder>/(<group>)/に移動し、ラベル、順序、collapsedを指定したmeta.tsを追加してください。かっこで囲まれたフォルダーはサイドバーにグループを追加しますが、URL セグメントは追加しません。そのため、ルートは変わらず、リダイレクトも不要です。また、別のフォルダーにあるページも、従来のルートを維持したslugを指定すればグループに追加できます。ランディングページが兄弟ファイルであるグループでも、すべての URL を維持できます。ランディングページを(group)/index.mdに移動し、slug: <そのページの従来のルート>を指定すると、スラッグを指定したインデックスページがグループのリンクになります。ページをより深いフォルダーに移動すると、相対リンクとアセット(./img.png、../other.md)が壊れるため、パスを付け直してください。(例外は Docsify です。従来の#/URL はパスにかかわらずスクリプトで再マッピングされるため、ページは実際のフォルダーに移動します。)構造を表現できない場合に限り、ページを実際のサブフォルダーに移動する(URL が変わるため、redirectsを追加します)か、明示的なnavigation.sidebarでグループを宣言してください。後者なら、ファイルを移動せずに既存のルートをネストできます。インベントリ作成時には、設定のpages/ナビゲーション配列を再帰的にたどり、設定のネストの深さがディスク上の深さを上回る箇所を記録してください。その差が、まさに失われる部分です。
タブとセレクター
navigation.tabs({ label, path, icon? })はヘッダー上部のセクションを表示し、ルートに応じてサイドバーを絞り込みます。タブのpathにあるフォルダーがセクションになるため、タブ以外の設定は不要です。コンテンツはタブごとに1つのフォルダーにまとめてください。ソースの最上位タブ(Mintlify のnavigation.tabs、最上位の製品/セクション切り替え)は、これらのヘッダータブに対応します。タブのまま維持し、単一のグローバルなnavigation.sidebarにまとめないでください。 Blume はURL プレフィックス(ルートのプレフィックスと一致する最長のタブpath)でアクティブなタブを選択するため、タブ内のすべてのページは、そのタブの単一のpathの下に配置する必要があります。任意のルートが混在するソースタブは、そのままでは移行できません。ページを1つのプレフィックスの下に移動する(ルート変更 →redirectsを追加する)か、最も近い構成を受け入れ、レポートでどちらにしたかを明記してください(詳細はreferences/mintlify.mdを参照)。フィルタリングは双方向に機能します。タブのpath配下のルートでは、サイドバーにはそのタブのフォルダーのみが表示されます(現在のルートがタブの配下にある場合、そのタブもハイライトされます)。ルートまたはタブに属さないルート(あるいはpathが/のタブ)では、タブのフォルダーは非表示になり、どのタブにも属さないページのみがサイドバーに表示されます(ツリー全体がフォールバックとして使われるため、空になることはありません)。移行時の留意点:タブを追加すると、ランディングページのサイドバーからセクション分けされたコンテンツが自動的に除外されます。これは意図した動作であり、ページが失われたわけではありません。そのための除外設定を手作業で作成しないでください。navigation.selectors({ kind, label, items: [{ label, path, icon?, description?, tag? }] }、kind=dropdown/product/version/language)は、現在のルートに応じて選択されるヘッダーのドロップダウンを使い、サイト全体(製品、バージョンなど)を区分します。navigation.actions([{ label, href }])はアイコンボタンの左側のヘッダーに通常のリンクを配置し、navigation.cta({ label, href }、単数形)はヘッダーに塗りつぶしスタイルのコールトゥアクションボタンを1つ配置します。ソースのヘッダーバーにはこれらを使用します。「Log in」や「Status」のリンクはactionsに、「Sign up」や「Get started」のボタンはctaに配置します。http(s)のhrefは新しいタブで開きます。内部ルートはビルド時にページと照合して検証されるため、同じホスト上の別のアプリが提供するルートは絶対 URL で記述する必要があります。ナビゲーション切り替えがないページのctaを除き、どちらもスマートフォン(sm未満)では非表示になります。ドキュメントページでスマートフォンでも表示する必要があるリンクは、featuredに配置してください。navigation.featured({ label, href, icon? })は、セクションの上にあるサイドバー最上部にリンクを固定します。ブログ、変更履歴、サポートページなど、常にワンクリックでアクセスできるようにしたいページに適しています。これらはタブのスコープ設定の例外です。生成されたツリーとは異なり、featured リンクはすべてのルートと画面幅で表示されます。hrefは任意の場所を指定できます。外部 URL は新しいタブで開き、内部ルート(/contact)はビルド時にページと照合して検証されます。ほかの箇所と同様に、iconには Lucide の名前(または画像パス/URL/インライン SVG)を指定します。Mintlify のアンカーやブログ/問い合わせリンクなど、ソースで常に表示されるヘッダー/ユーティリティリンクにはこちらを使用してください。references/mintlify.mdを参照してください。
ルートとパス
- ルートは
content.rootからの相対コンテンツパスです。数字のプレフィックスは削除され(01-intro.mdx→/intro。ただし、バージョン名や名前が日付YYYY-MM-DD、D-M-YYYY/M-D-YYYY、YYYY-MMで始まる場合はそのまま保持されます。12-05-2022.mdx→/12-05-2022。旧サイトで数字から始まるほかの名前がそのまま使われていた場合は、slugを指定してください)、(group)/フォルダーはパスのセグメントになりません。indexファイルは、そのフォルダーのルートに対応します。フロントマターのslugは生成されるルートを上書きします。README.mdはフォルダーのインデックスではなく、/READMEの通常のページとして扱われます。README をインデックスとして使う Docsify、MkDocs、GitBook、VuePress のソースでは、ファイル名をindex.mdに変更してください。
blume.config.ts の形式
defineConfig({...}) — すべてのフィールドは省略可能で、既定値が設定されています。
- Site:
title、description、logo(SVG の文字列、または{ image: string | { light, dark, alt }, text, href })、banner(文字列、または{ content, link: { href, text }, dismissible, id }— 色や type はありません)。ロゴはヘッダーのtitleの横に描画されるため、ワードマークのロゴはブランドを二重に表示します(「Acme Acme」)— マークのみを描画するにはtext: ""を設定してください。{ light, dark }よりも文字列形式を優先してください: ロゴ SVG をローカルに持っていて、それがモノクロ(単色の黒または白)の場合、そのfill/strokeをcurrentColorに書き換えてlogo: "/logo.svg"を使用してください — そうすればテーマのテキスト色を継承し、ライト/ダークに自動的に適応するため、別々のライト/ダークファイルは不要です。 theme:accent(両モード共通の色文字列、またはモードごとの{ light, dark })、action(色)、mode(light/dark/system)、radius、fonts({ body, display, mono }— それぞれが厳選された Google フォントのスラッグ、任意の Google/Fontsource/Bunny/Fontshare ファミリー向けの{ name, provider?, weights? }オブジェクト、またはローカルフォントファイル向けの{ name, variants: [{ src, weight?, style? }] })、backgroundとbackgroundImage(それぞれ文字列、またはモードごとの{ light, dark })。旧来のaccentDark/backgroundDark/backgroundImageDarkフィールドはこれらのモード別オブジェクトに統合されました — 裸の文字列は引き続き両モードに適用されるため、2 つのモードが異なる場合にのみ{ light, dark }を使用してください。各色は CSS 色またはアクセントプリセット(ソースの裸の"3b82f6"には#が必要)でなければならず、そうでない場合はBLUME_THEME_COLOR_INVALIDが警告を発し、ブラウザはそれを無視します。theme.strictは存在せず、theme.css構成フィールドも存在しません — カスタム CSS はプロジェクトルートのtheme.cssファイルに記述します(自動的に読み込まれます)。また、ソースの「strict appearance」フラグは廃止されます。content:root(デフォルトは"docs"で、blumeを実行するプロジェクトディレクトリからの相対パス)、include/exclude(content.rootからの相対の glob の配列。デフォルトは["**/*.{md,mdx}"]/["**/_*", "**/.*"]— 設定されたexcludeはそれらのデフォルトに追加され、そのためパーシャルとドットフォルダは非公開のままになります。_で始まるファイルやドットファイルを意図的に公開するには、デフォルトを!付きで記載します:exclude: ["!**/_*"])、sources(blume/sourcesからインポートされたアダプターの配列:filesystem({ root, include, exclude })、obsidian({ vault })、githubReleases({ owner, repo })、notion({ database })、sanity({ projectId, dataset, query })、contentful({ space, contentType })、payload({ url, collection })、strapi({ url, contentType })、mdxRemote({ github })、custom(source)。options オブジェクトを取るすべてのファクトリーはprefixとpollIntervalも受け取りますが、custom(source)は自身のprefixを設定するContentSourceインスタンスを受け取ります。1.x の{ type: "…" }オブジェクトは削除されました —typeをファクトリー呼び出しに名前変更し、他のフィールドをその options として渡してください — ただし{ type: "custom", source }は例外で、これはインスタンスを唯一の引数としてcustom(source)になります。root/include/excludeは単一のfilesystem()の省略形であり、sourcesと併用すると拒否されます — それらをfilesystem()エントリに移動してください。OpenAPI/AsyncAPI/GraphQL はこれらの中には含まれません。それらはトップレベルのreferenceリスト内のアダプターです)、pages(カスタムの.astroディレクトリ)、defaultType。ドキュメントがプロジェクトディレクトリ直下にある場合(docs/サブフォルダがない場合)、そこにrootを設定し、includeを実際のコンテンツフォルダに限定してすべてをスキャンしないようにしてください —references/monorepo.md§1。basePath(トップレベル): サイト全体のマウントポイント(例:"/docs")で、すべてのルートの先頭に付加されますが、サイドバーからは見えません(ラッパーグループなし)。これは、すべてのドキュメントをプレフィックスの下で提供していたソース(Docusaurus のrouteBasePath、/docsの Fumadocs のbaseUrl)に対する適切なターゲットです — ソースごとのprefix(ナビグループを追加する)やdeployment.base(ホストのサブディレクトリ)とは異なります。navigation:tabs、selectors、actionsとcta(ヘッダーリンクと塗りつぶしボタン1つ)、featured(すべてのルートでサイドバーの上に固定されるリンク)、sidebar({ display, items }—displayは上記のグローバルなレンダリングモード、itemsは明示的なツリー)、repo(true/false、またはドキュメントリポジトリがプライベートでgithubを未設定のままにしなければならない場合のフッターの GitHub リンク用の絶対 GitHub URL)。どうしても必要な場合を除き、明示的なnavigation.sidebarは避けてください — ファイルシステムから導出されるサイドバーに頼ってください。これはファイルツリーが意図するサイドバーレイアウトとほぼ一致する場合にのみ機能するため、まずフォルダを意図するレイアウトに合わせて整形してください。sidebar.itemsに頼るのは、ファイルが本当に表現できない形状の場合のみです(上記の「Config-declared nesting」を参照)。search—blume/searchからインポートされたアダプター:orama()(デフォルトなので、これにはsearchを完全に省略します)、flexsearch()、pagefind()、algolia({ appId, apiKey, indexName })、oramaCloud({ endpoint, apiKey, indexId? })、typesense({ host, collection, apiKey })、mixedbread({ storeId })、または無効化するfalse。アダプターを直接渡す(search: algolia({…}))か、厳選リンクやインデックスオプションも設定する場合はsearch: { provider, popular, indexing }として渡します。Blume 1.x のsearch.provider文字列と、そのsearch.algolia/oramaCloud/typesense/mixedbread認証情報ブロックは廃止されました — ソース構成(または古いblume.config.ts)にprovider: "algolia", algolia: { appId, indexName, searchApiKey }がある場合、search: algolia({ appId, indexName, apiKey: searchApiKey })と書き換えてください(検索専用キーは、それを受け取るすべてのアダプターでapiKeyになりました。管理者キーは環境変数に残します)。ai(アシスタント、Open in chat —ai.assistant.providerはblume/aiからインポートされたアダプター記述子を受け取ります:gateway({ model })(デフォルト、openai/gpt-5.5)、openai({ model })(または任意の OpenAI 互換エンドポイント向けのopenai({ baseUrl, name, model, apiKeyEnv }))、anthropic({ model })、gemini({ model })、grok({ model })、openrouter({ model, reasoning })、llmgateway({ model })、またはinkeep({ model })。すべてのアダプターはmodel、apiKeyEnv、headers、そしてそのまま渡されるproviderOptionsパススルーを受け取ります(headersの値は生成されるルートソースにそのまま書き込まれるため、これらは秘密でない静的ヘッダー専用です — ベアラートークンやその他の認証情報は、apiKeyEnvが指定する環境変数に属し、headersには決して入れません)。inkeep()を除くすべてのアダプターはreasoningも受け取ります。Inkeep は独自の回答パイプラインを実行するため、inkeep({ reasoning })は認識されないキーで検証に失敗します — そこではソースの reasoning 設定を削除し、それを報告してください。ai.assistantにフラットなprovider/model/apiKeyEnv/baseUrl/headers/reasoningフィールドは存在しません — AI アシスタントをそのように構成していたソース(Blume < 2.0 を含む)は、1 回のアダプター呼び出しにマッピングされます。enabled、instructions、retrieval、suggestions、cors、endpointはai.assistant自体にあります。ai.askは存在しません — Blume 2.0.0 以前はその名前を使用していたため、古いblume.config.tsはブロック全体をai.assistantに移動します)、agents(llms.txt、JSON API、MCP サーバー、公開された skills、discovery マニフェスト、robots content signals)、reference(blume/referenceからインポートされたアダプターのリスト —openapi({ spec | sources, route, … })、asyncapi({ … })、graphql({ spec, endpoint, … })— 1.x のopenapi/asyncapi/graphqlブロックは決して使用しません)、redirects、seo、markdown、analytics(blume/analyticsからインポートされたアダプターのリスト — プロバイダーごとに 1 つのファクトリー(posthog({ key, host })、googleAnalytics({ id })、plausible({ domain, host })、mixpanel({ token, region })、segment({ key })、…。ドキュメントページにすべてが掲載されています)、vercel()、およびそれがないもの向けのscript({ src | content, strategy, attributes })— プロバイダーをキーとするオブジェクトは決して使用しません)、deployment、i18n、toc、lastModified、github({ owner, repo, branch?, dir?, host?, api? }— ソースの編集 URL がgithub.comではなく GitHub Enterprise のオリジンにある場合は常にhostを設定してください)。analytics—blume/analyticsのアダプターで、ソースのカスタム head スクリプト向けのscript()を含みます。ソースの head スクリプト内の既知のアナリティクススニペット(gtag ローダーとgtag('config')のペア、GTM、Plausible など)は、script()ではなくそのプロバイダーのファクトリーになります。アダプターは本番ビルドでのみ読み込まれ、consentが構成されている場合はそれを待ちます。そのため、ページが動作するために必要なスクリプト(サポートウィジェット、フォーム埋め込み)は、代わりにPageFooterレイアウトスロットコンポーネント(defineComponents)に配置してください。deploymentはblume/deployのホストアダプター —vercel()、netlify()、cloudflare()、またはnode()— あるいは任意のホストでの静的ビルド向けの単なる{ site, base }です(デフォルトは静的ビルド)。ホストアダプターを指定すると、そのホスト上でビルドがサーバー出力に切り替わります(そこで静的のままにするにはoutput: "static"を渡します)。site、base、outputが名前付きオプションで、それ以外は基盤となる@astrojs/*アダプターにそのまま転送されます。deployment.adapter文字列は存在せず、deployment.outputフィールドも存在しません。サーバーレンダリングを必要とするソース(アシスタント、MCP サーバー、Mixedbread 検索、API プレイグラウンドプロキシ)はimport { vercel } from "blume/deploy"とdeployment: vercel()を使用します。静的ソースは何も設定しません — ただしドキュメントをサブパスの下で提供していた場合は別で、それはdeployment: { base: "/docs" }になります(siteをいつ追加するかは以下を参照)。cloudflareとvercelはblume/analyticsからもエクスポートされていることに注意してください — 構成で両方を使用する場合は、いずれかにエイリアスを付けます(import { cloudflare as cloudflareDeploy } from "blume/deploy")。- ターゲットホストが Blume が自動検出するホストのいずれかでない限り、ソースのサイト URL を
deployment.siteとして保持してください。 Blume はVercel と Netlify でのみ(その安定した本番ドメインで)プラットフォームのビルド環境からsiteを補完し、blume dev中は dev サーバーのlocalhostURL を使用します。これら 2 つのホストでは、未設定のままにして検出にデプロイされた URL を選ばせてください。それ以外のすべて — Cloudflare Pages(デプロイごとのCF_PAGES_URLのみを公開します)、GitHub Pages、S3 や他の静的ホスト、カスタム CDN、Cloudflare Workers、node()サーバー — では何も検出されず、siteが未設定だとサイトマップ、OG 画像、RSS フィード、AI カタログ、絶対 canonical URL が黙って失われます。したがって、ソース構成にurl/siteフィールドがあり、ターゲットがそれら 2 つのホストのいずれでもない場合、それを引き継いでください: 静的ビルドならdeployment: { site: "https://…" }、ホストアダプターのsiteオプション(node({ site }))です。サイトがどこにデプロイされるか判断できない場合は、それを保持し、レポートでその旨を述べてください。 - Favicon はファイル名の規約であり、構成ではありません。
icon.{svg,png,ico}またはfavicon.{svg,png,ico}(およびapple-icon.pngまたはapple-touch-icon.png)をプロジェクトルートまたはpublic/に置いてください — Blume が自動検出します。favicon構成フィールドは存在しません。{ light, dark }として指定されたソースの favicon は、ファイル名のペアにマッピングされます: ライトファイルを慣例的な名前にコピーし(例:public/icon.png)、ダークファイルをその-darkの兄弟ファイルにコピーします — 同じディレクトリと拡張子で、拡張子の前に-dark(public/icon-dark.png)。2 つのファイルの形式が異なる場合は、拡張子が一致するようにいずれかを変換してください。解決されたアイコンの正確な兄弟ファイルのみが読み込まれます。 スキーマはblume/schemaからエクスポートされます。フィールドの完全なリファレンスは、インストール済みのblumeパッケージのdocs/configuration/ディレクトリにあります(場所の確認方法は、以下の「完全なドキュメント」を参照してください)。
アイコンはLucideのみです
Blumeでは、アイコンを指定できるすべての場所で、Lucideのハイフン区切り小文字の名前(Lucide)を使用します。対象は、frontmatterのicon、sidebar.icon、meta.tsのicon、navigation.tabs/selectorsのアイコン、およびCard/Step/Iconなどのpropsです。FontAwesomeやTablerには対応しておらず、iconType propもありません。名前はハイフン区切りの小文字(BookOpenではなくbook-open)にする必要があります。PascalCaseのReactコンポーネント名(Fumadocs/lucide-reactのソースでよく使われます)は解決されず、何も表示されません。別のアイコンセットを使っているソース(MintlifyとFernではFontAwesomeを使用)を移行する場合は、各アイコン名を最も近いLucideのアイコンに置き換えてください。該当するアイコンがない場合は、そのアイコンを削除して、その旨を報告してください。使用する前に、lucide.dev/iconsでアイコン名が存在することを確認してください。
ページのfrontmatter(厳密 — 未知のキーがあるとビルドエラーになります)
---
title: Install # renders as the page H1 — remove any duplicate H1 in the body
description: Install Blume and scaffold your first project.
type: doc # doc (default); blog and changelog drive feeds, other values only mean something under content.types
sidebar:
label: Install # overrides title in the sidebar
order: 2
icon: download
badge: New
hidden: false
seo:
title: …
description: …
image: /og/install.png
canonical: https://…
noindex: false
search:
exclude: false
tags: [api]
slug: install # override the generated route
draft: false
lastModified: 2026-06-20 # pin the "last updated" date
---
このほか、date/authors(ブログ/変更履歴フィード用)、changelog(変更履歴メタデータ用)、deprecated、およびトップレベルの省略記法hidden(sidebar.hidden用)とnoindex(seo.noindex用)も有効です。
オーサリング機能(.mdxでインポート不要)
- 豊富な機能は MDX 専用です。 ディレクティブ、
package-install、mermaid、数式は MDX プロセッサに組み込まれています。プレーンな.mdファイルでは、:::noteはリテラルテキストのままになり、ビルドはグリーンのままですが、その行でBLUME_MD_DIRECTIVE警告が表示されるだけです。移行中に、これらの機能を使用する(または使用すべき).mdファイルはすべて.mdxに名前を変更してください。 MDX は Markdown よりも厳格な記法です。タグを開かない非スペース文字が続く<(<7、<50 ms、<= 5、List<T>)や、単独の{または}はビルドを失敗させるため、名前を変更するページではそれらをエスケープしてください(<または\<、および\{)。lastModified: "git"の場合、移行で編集されたすべてのページに移行コミットの日付が表示されるため、サイトが日付を表示する場合はレポートでその旨を記載してください。名前の変更や移動だけが行われたページは日付を保持します(Blume は名前の変更を追跡します)。これは、.mdコンテンツが:::アドモニションで溢れている Docusaurus/Starlight ソースで最も深刻な影響を及ぼします。プレーンな Markdown(見出し、テーブル、タイトル/ハイライト付きのフェンスコード)は.mdで問題ありません。 - ディレクティブとしてのコールアウト:
:::note、:::tip、:::warning、:::danger、:::info、:::success。オプションでブラケット内にタイトルを指定でき、そのインライン Markdown がレンダリングされます::::warning[Heads up]。エイリアスはcaution→warning、error→danger、important→note、warn→warning です。独自のアイコンや色合いが必要なコールアウトは<Callout type icon color title>(Lucide のicon、任意の CSScolor)で、これはディレクティブでは設定できません。markdown-it ソース(VitePress、VuePress、Docusaurus v2)は::: tip Titleと書きます。コロンの後にスペースがある場合、.mdxであっても決してディレクティブにはならず、リテラルテキストとしてレンダリングされます(.mdxはコールアウト名に対してのみBLUME_DIRECTIVE_SPACED_NAMEを警告します)。開いている:::コンテナ内では、そのコンテナを閉じてしまい、そのテキストは破棄されます(BLUME_DIRECTIVE_CLOSING_TEXT)。名前に続くタイトル(:::tip Title)も同様に破棄されます(BLUME_DIRECTIVE_OPENING_TEXT)。:::tip[Title]に正規化してください。MDC の 2 コロンブロック(Docus、任意の Nuxt Content サイト:::note…::)は Blume にとってリーフディレクティブであり、テキストとして出力されます(BLUME_MDC_SYNTAX)。また、MDC の[text]{.class}スパンは MDX ビルドを失敗させます(BLUME_MDX_ATTRIBUTE_LISTがその行を報告します)。GitHub アラート(> [!NOTE]、GitHub の 5 種類のいずれか、[!CAUTION]は danger として扱われます)は.mdxではコールアウトとしてレンダリングされ、マーカーの後のテキストがタイトルになります。.mdではマーカーを表示する引用のままになるため(BLUME_MD_GITHUB_ALERT)、これらのページは.mdxに名前を変更してください。 - インポート不要の MDX コンポーネント:
Callout、Card/CardGroup、Columns/Column、Steps/Step、Tabs/Tab、Accordion/AccordionItem、Expandable、FileTree、Tree/Tree.Folder/Tree.File、CodeGroup、Frame、Panel、Tooltip、Tile、Badge、Icon、TypeTable/AutoTypeTable、Color、YouTube、Visibility、GithubInfo、Component、CodeBlock、Diff、Prompt、Math、Changelog、および手書きのエンドポイントフィールドParamField/ResponseField/RequestExample/ResponseExample(Mintlify のセマンティクス:<ParamField path|query|header|body="name">はフィールドをその場所によって命名します。docs/references/api-pages.mdxを参照してください)。(同梱されていません — 変換してください:<Warning>/<Note>/<Info>/<Tip>/<Check>/<Error>→ 対応する:::ディレクティブ、およびRequestField。Fern や Mintlify が行うように、codeプロパティなしでフェンスのラッパーとして使用される<CodeBlock>は、フェンスをそのままレンダリングしますが、自身のtitleは無視されます。フェンスを展開し、タイトルをそのメタに配置してください。子要素を表示するコンポーネントを、子要素なしで別のツールのプロパティと共に使用した場合(<Badge type="tip" text="beta" />)、空でレンダリングされ、BLUME_UNKNOWN_PROPを警告します。コンテンツをタグの間に配置してください。ターゲットについてはリファレンスファイルを参照してください。) - フェンスコードの超能力:
```package-install→ パッケージマネージャーのタブ、```mermaid→ レンダリングされた図、コードブロックのタイトル(```ts server.ts)、行番号(lineNumbers)、ハイライト({1,4-5}、// [!code ++])。 - 移行を妨げるフェンスとタイトル: Shiki が認識しないフェンス言語はプレーンテキストとしてレンダリングされ、
BLUME_UNKNOWN_CODE_LANGUAGEを警告します(大文字小文字は関係ありません:JSONはjsonと同じようにハイライトされます)。id を修正するか、プレーンテキストにはtextと書いてください。言語が属性とカンマで繋がれているもの(```rust,ignore)もその 1 つです。代わりにスペースを入れた場合、rustdoc や mdBook のキーワード(ignore、no_run、should_panic、edition2021、editable、…)はBLUME_CODE_FENCE_OPTIONを警告し、タイトルには含まれませんが、それ以外の 2 番目の単語はブロックのタイトルになります。言語のみを残してください。他のツールのフェンスオプション(hl_lines="2 3"、linenums="1"、showLineNumbers、Mintlify のlines、wordWrap、filename="…")は何もせず、タイトルにも含まれず、Blume の書き方({2,3}、lineNumbers、wrap、title="…")でBLUME_CODE_FENCE_OPTIONを警告します。オプションはあるが言語がないフェンスには言語が必要です(```text title="x" lineNumbers)。そうでなければ最初のオプションが言語として読み取られます。タイトルは言語の後のすべての単語で、ブラケット付きのもの(```ts [file.ts]、VitePress と MDC 由来)はブラケットが外れ、その後に範囲が繋がっている場合([file.ts]{2})はその行がハイライトされます。Expandable、AccordionItem、コールアウトのタイトルはインライン Markdown(コード、強調、リンク)をレンダリングしますが、Stepのタイトルはプレーンな文字列で、Markdown は書かれたとおりに表示され、アンカーもないため、アンカー付きの見出しを<Step>内の最初の行として保持してください。生の HTML<img src>と<a href>は決して最適化されません。ページの隣にあるファイルを指す相対パスは、そのファイルをページと共に公開し([spec](./spec.pdf)や<Card img="./cover.png">がそうであるように)、ルートパスには Markdown リンクと同様にdeployment.baseが付与されます。また、blume validateは両方をチェックしますが、ページへの相対<a href>はページのフォルダではなくページの URL に対して解決されます。画像を Markdown に変換して最適化されるようにし、ページリンクを Markdown リンクまたはルートルートに変換してください。 - 数式:
$$…$$は.mdxで設定なしでレンダリングされます(markdown.mathフィールドは存在しません)。単独の行のブロックとして、または文中のインラインとして使用できます。単一の$は常にリテラルテキストのままなので、各インライン$…$をその場で、文中で(単独の行にはせずに)$$…$$に変換し、すべてのペアが数式であり通貨やシェル変数ではないことを確認してください。
OpenAPI
reference: [openapi({ sources: [{ spec, label?, route? }] })] — blume/reference からインポートされる openapi() アダプター(spec は単一ソースの省略記法)は、オペレーションごとに 1 つの実際のページを生成します — ルーティング、サイドバー、検索、OG 画像もそのまま利用できます。リファレンスにはヘッダータブが自動的には付きません — アダプターの route を指す navigation.tabs エントリを追加してください(リファレンスのルートは有効なタブのターゲットです)。そうしないと、ヘッダーから API リファレンスに到達できません。生成された API リファレンスページを手作業で移行しないでください(ソース内のエンドポイントごとのスタブページ):それらを削除し、openapi() を spec に向けてください。代わりにソースの Scalar 埋め込みを保持するには、openapi() の代わりに reference 内で scalar({ spec, theme?, …scalarOptions })(blume/reference から同様にインポート)を列挙します。これは OpenAPI または AsyncAPI ドキュメントをソースごとに 1 つの埋め込みページとしてレンダリングし、名前を付けていないすべてのキーをそのまま Scalar に転送し、ネイティブの表示オプション(codeSamples、expandSchemas、playground)は受け取りません。openapi()/asyncapi() に renderer オプションはありません — 検証に失敗します。Blume 1.x のトップレベル openapi/asyncapi/graphql ブロックは廃止されました — ソース設定(または古い blume.config.ts)に openapi: { enabled: true, ... } がある場合は、それを reference のエントリとして書き換え、enabled を削除してください。renderer: "scalar" を含む 1.x ブロックは、代わりに独自の scalar({ … }) エントリになり、そのブロックの route、sources、noindex を保持し、その theme と scalar: { … } オブジェクトのキーを scalar() にそのまま渡します(scalar({ spec, theme: "purple", localization }))。
- デフォルトで仕様をベンダー化する。 リモートの
spec:URL は、ビルドのたびにビルド時に取得することに依存させてしまいます。これは CI やオフライン、プロキシ環境における単一障害点となり、取得に失敗すると参照全体がスキップされます。仕様をリポジトリにコミットし(openapi/<name>.json)、specをローカルパスに向けることを推奨します。ソースがそれをpublic/openapi.jsonとして提供している場合は移動してください(読者がダウンロードする場合はpublic/specs/openapi.json)。その URL は Blume が自身のドキュメント API 記述を公開している場所です(BLUME_PUBLIC_OPENAPI_JSON)。URL を維持する場合は、その旨を明記し、フォールバック付きでローカルコピーを更新するprebuildステップの検討をおすすめします。 - オペレーションのルートには独自のスラッグ体系があります —
<route>/<slugified-tag>/<slugified-operationId>(例: タグModels、idlistModels→/api-reference/models/list-models)。camelCase または PascalCase のタグやオペレーション id は、スラッグ化する前に単語境界で kebab-case に分割されます(InboxesThreads→inboxes-threads、getHTTPResponse→get-http-response)。したがって、単に小文字化するだけではいけません。operationIdを持たないオペレーションは、代わりにそのメソッドとパスを使用します(GET /pets/{id}→get-pets-id)。スラッグはそのタグ内で一意であればよいだけです。同じタグ内の2つ目のlistにはメソッドが追加されます(list-post)。これはソースのエンドポイントリンクとほとんど一致しないため(Mintlify などは異なる方法で kebab-case 化します)、オペレーションへのすべてのインバウンドリンクを書き換えてください。blume validateはオペレーションのページを他のルートと同様に解決するため、見逃したものを検出できます。 - 独自のパスで提供される仕様(Redocly は
apis/x/openapi.yamlを/apis/x/openapiで提供):ソースのrouteを設定して、サイドバーが許す限り概要が以前の URL を維持するようにしてください(フォルダルートのほうが読みやすい場合については、ソースのリファレンスに記載があります)。オペレーション、タグ、セクションの URL には依然としてリダイレクトが必要です。 - オペレーション URL のリダイレクトは古いサイトマップから取得し、オペレーションごとに1つの正確なエントリを、手入力ではなく生成します。一度ビルドしてから、
node <skill>/scripts/operation-routes.mjs distを実行すると、各リファレンスのエンドポイント(GET /pets/{id})が対応する Blume ルートにマッピングされたものが、ビルドから読み取られて出力されます(--spec <route>=<file.json>で operationId を追加できます)。各古い URL を、仕様を通じてそのエンドポイントに照合してください。インバウンドリンクは追加する前に書き換えてください。blume validateはリダイレクトのfromを有効なリンクターゲットとして受け入れるため、リダイレクトが存在すると古い形式のリンクを指摘しなくなります。 - タグのラベルと順序は仕様から取得します。 タグの
x-displayNameがそのグループのラベルになります。タグは仕様のtagsリストに従い、オペレーションは記述されたとおりにそのパスとメソッドに従います。x-tagGroupsは読み取られません。ソースがそれで並べていた場合は、各タグに<route>/<tag-slug>/meta.ts→defineMeta({ order })を与え、フラット化されたx-tagGroups内でのその位置を指定してください。タグフォルダーのmeta.tsは生成された設定にマージされるため、異なる部分だけを設定します(title、order、またはオペレーションを並べ替えるpagesリスト)。スコープ付きのcontent.includeの下では、そのタグフォルダーに到達する glob を追加してください。そうしないとそのファイルは決して読み取られません(BLUME_META_OUTSIDE_INCLUDE)。 - ソースが生成されたエンドポイントページに付加した散文(ReadMe と Mintlify はこれを許可しています)は、そのオペレーションの
descriptionに属し、オーバーレイで設定します。Markdown と:::ディレクティブはオペレーションページにレンダリングされますが、JSX はそうではありません(<と{はエスケープされます)。 - OpenAPI 以外の形式で定義された API(Fern Definition)は、まず OpenAPI にエクスポートされます。その方法はソースのリファレンスに記載されています。
- Try it リクエストは読者のブラウザーから直接送信されます。 各 API サーバーで CORS を調査してください(
curl -si -X OPTIONS -H 'Origin: https://<docs-host>' -H 'Access-Control-Request-Method: GET' <server>/<path>)。一致するaccess-control-allow-originがないものをフォローアップとしてリストアップします(サーバー出力のホストではplayground: { proxy: true }で修正できます)。または、それらのプレイグラウンドをオフにしてください。 - 手書きの概念ページは残してください。 ソースは多くの場合、書かれた「Introduction/Authentication」ページとエンドポイントグループを同じタブに組み合わせています。
openapi()アダプターのrouteの下に配置された通常のコンテンツページは、リファレンスタブのサイドバーにマージされます。したがって、それら(認証、エラー、レート制限)は残し、エンドポイントごとのスタブだけを削除してください。
GraphQL
reference: [graphql({ spec, endpoint? })] は GraphQL に対応する機能です。Blume はスキーマ(SDL テキストまたはイントロスペクション JSON の結果、ローカルパスまたは URL)を、ルートフィールドごとの実ページ(Queries/Mutations/Subscriptions に分類)と、名前付き型ごとのページ(Objects、Input Objects、Enums、Interfaces、Unions、カスタム Scalars)に変換します。上記の OpenAPI のルールはすべて適用されます。ソースの生成済み GraphQL リファレンスページを手作業で移行しないでください(削除して、spec にスキーマを指定してください)。リモートスキーマはローカルに取り込み、手書きの概念ページは route(デフォルトは /graphql)の下に置き、navigation.tabs エントリーを追加し、リンク元のリンクを書き換えてください。ルートは <route>/<slugified-group>/<slugified-name>(例:/graphql/queries/pets、/graphql/objects/pet)となり、blume validate で他のページと同様に解決されます。openapi() アダプターとの違いは次のとおりです。
endpointには稼働中の GraphQL URL を設定してください。 OpenAPI ドキュメントとは異なり、スキーマにはサーバーが記載されていません。endpointは Try It プレイグラウンドとコードサンプルの接続先です(設定しない場合はプレースホルダー URL が表示され、playground: { proxy: true }は許可するオリジンがないため、ビルド時に警告されます)。複数のスキーマを使う場合は、sources: [{ spec, endpoint?, label?, route? }]を使います。ソースごとのendpointはアダプターレベルの設定より優先されます。- Scalar の埋め込みには対応していません — GraphQL スキーマ向けの
scalar()に相当するものはありません(また、graphql()はexpandSchemasを受け取りません)。リファレンスは常に Blume でレンダリングされます(Scalar の埋め込みが読み込めるのは OpenAPI および AsyncAPI ドキュメントのみです)。ソースに GraphQL プレイグラウンド/エクスプローラーの埋め込み(GraphiQL、Apollo Explorer)がある場合、組み込みの Try It パネル以外に直接相当するものはありません。パネルでは実現できない機能があれば報告してください。 - 受け付けるのは SDL とイントロスペクション JSON のみです。 プログラムでスキーマを構築するソース(コード内の
GraphQLSchemaインスタンス)は、SDL に出力して(graphqlのprintSchemaを使用)、コミットする必要があります。この変換について報告してください。
Changelogs
ソースに手作業で管理された変更履歴(changelog.mdx、日付別エントリーのフォルダー、Mintlify の <Update> ブロック、ReadMe の changelogs/ フォルダー)があり、リリースノートがそのリポジトリの GitHub リリースで公開されている場合は、githubReleases() コンテンツソースへの置き換えを提案してください。リリースノートが自動的に変更履歴になり、管理するファイルが不要になります。これは提案であり、自動的に置き換えるものではありません。GitHub リリースと 1 対 1 で対応しないように編集された変更履歴を維持しているチームもあるため、ページを削除する前に、リリースノートが信頼できる唯一の情報源であることを確認してください。
ファイルシステムソースとともに content.sources に追加します(どちらも blume/sources からインポートします。sources がある場合、コンテンツルートは filesystem() の中に移動します)。
import { filesystem, githubReleases } from "blume/sources";
content: {
sources: [
filesystem({ include: ["docs/**/*.mdx"], root: "." }),
githubReleases({
owner: "haydenbleasel",
repo: "ultracite",
prefix: "changelog",
}),
],
},
- 各リリースは
/<prefix>/の下にtype: changelogページとして生成されます(prefix: "changelog"→/changelog/…)。ルート直下に配置する場合はprefixを省略します。 - オプションのフィールド:
limit(生成するリリース数の上限。新しい順。デフォルトは 100)、prereleases(プレリリースを含める)、drafts(ドラフトを含める。リポジトリへの書き込みアクセス権を持つトークンが必要)、pollInterval(開発時のポーリング間隔を秒数で指定。セッション中は更新しない場合は省略)。 - 非公開リポジトリでは、
GITHUB_TOKENからトークンが読み込まれます。設定にトークンが直接埋め込まれることはありません。アダプターでトークンが宣言されているため、未設定の場合はblume dev/buildが警告します。公開リポジトリではトークンなしでも動作します。 - ソースを接続したら、古い変更履歴ページを削除し、以前のルートから新しい
/<prefix>/…スラッグへのredirectsを追加してください。ソースにヘッダー/サイドバーリンクがあった場合は、navigation.featuredで固定します。古い変更履歴の紹介文をリストの上に残すには、紹介文と<Changelog />を記述したchangelog/index.mdx(mode: center)を作成してください。<Changelog />は生成されたリリース一覧を表示します。
リダイレクトは静的です
blume.config.ts 内の redirects: [{ from, to, status? }] 配列は、ルートを再構成するときに古い URL をマッピングします — Blume はこれらを自身で配信するため、ページを移動するあらゆる再編成(タブごとのフォルダ、実体化されたネストグループ、名前を変更したスラッグ、インデックスの昇格)は、そこにエントリを追加するだけで修正できます。ホスト側の設定は不要です。再構成はこれらの主な発生源です: ステップ 4 で移動したすべてのページ(タブごとのフォルダ、名前を変更したスラッグ、インデックスの昇格)にはエントリが必要です。そうでなければ古い URL は 404 になります。status のデフォルトは 301(永続 — ブラウザーは無期限にキャッシュします) です。これは本当の移動には正しい設定ですが、取り消す可能性のあるリダイレクトには決して 301/308 を使用しないでください。パターンは書かれたとおりに引き継がれます: :name は 1 つのセグメント、:name* または末尾の * はパスの残り全体に対応します({ from: "/beta/:slug*", to: "/v2/:slug*" })。パターンは同時にページにもマッチすることはできないため、保持したページをカバーしているとビルドが失敗します(BLUME_REDIRECT_MATCHES_PAGE)。パターンを狭めてください。パターンで表現できないルール(正規表現パラメータ、ヘッダーや Cookie の条件)はホストレベルの設定(_redirects、vercel.json)に移してください。それらを報告してください。
from がページのルートと等しいリダイレクト(生成されたリファレンス概要を含む)は BLUME_REDIRECT_MATCHES_PAGE を警告し、優先されます: そのページは決して公開されません。リダイレクトを削除するか、ページを移動してください。ページの Markdown ミラー(/x.md、/x.mdx、ホームページの /index.md)についても同様です: エージェントがそれを見失うため、リダイレクトを削除してください。ページ自身のフォルダ URL(/x/、ソースが末尾スラッシュ付き URL を配信していた場合によくあります)からのリダイレクトも決して書かないでください: 同じようにそのページを乗っ取ってしまいます。/x/index.html からのもの(.html URL を配信していたソース)は無害ですが不要です: 静的ホストは x/index.html からそのページを配信するため、静的ビルドはそのためのリダイレクトページを書き出さず、ホストファイル(_redirects、vercel.json)だけがそれを保持します。そして redirects はパスのみにマッチします: ページが # の後に位置する URL は決してそこに到達しません(references/docsify.md を参照)。古いサイトがあなたの管理下にないホスト(GitHub wiki)にある場合、どのリダイレクトもその URL に到達できません: 何も約束しないでください(そこで何ができるかは references/github-wiki.md を参照)。末尾スラッシュには独自のリダイレクトは不要です: blume dev と blume preview は /a/ に対して /a への 301 を返します(クエリは保持)、ページとリダイレクトソースの両方に対して、Vercel と同様です。他の静的ホストは /a/ を a/index.html から配信し、サーバービルド(vercel()、node())はリダイレクトの from に対して /a/ にマッチします。静的ホストのリダイレクトルールがスラッシュ付きの from にマッチするかどうかはホストに依存するため、古いリンクが末尾スラッシュを使用していた場合は、プレビューデプロイで 1 つ確認してください。Netlify では、deployment: netlify({ output: "static" }) を設定してください: そのビルドの _redirects ルールのみが強制(301!)されるため、これがないと Netlify は各 from で Astro が書き出すメタリフレッシュページを実際の 301 ではなく 200 で配信します(素の netlify() はサーバー出力に切り替わります)。
検証とレポート
blume buildを実行します。これにより、フロントマターのスキーマ、ルートの重複、設定が検証され、デフォルトではエラー診断があると失敗します(--no-strictは指定しないでください。指定するとビルドは続行され、無効なフロントマターや解析できない.mdxを含むページが黙って除外されます)。続いてblume validate --strictを実行します。リンク、見出しアンカー、アセット、リダイレクト先はbuildではなくこちらで検証されます(外部 HTTP リンクも確認するには--externalを追加します)。OpenAPI のオペレーションページもvalidateの対象となる実際のルートなので、それらへのリンク切れも検出されます。両方の検証で問題がなくなるまで修正を繰り返します。ページ内に別のツールの構文が残っているとbuild(またはblume check)が出力する警告(BLUME_TEMPLATE_TAG、BLUME_MDC_SYNTAX、BLUME_WIKILINK_UNSUPPORTED、BLUME_MD_*、BLUME_CODE_FENCE_OPTION、BLUME_MDX_*など)は、変換漏れとして扱ってください。それぞれにファイルと行、Blume での表記が示され、validate --strictはこれらがあると失敗します。validateはページのレンダリング結果に基づいてリンクを読み取ります。同じラベルを持つ先行のリンク定義に隠れているリンク定義は検証されません(無効なテキストなので削除してください)。コメント内のリンクも検証されません。validate --strictは OpenAPI 仕様の警告(BLUME_OPENAPI_*。未宣言のパスパラメーター、localhostのサーバー、3.1 仕様でのnullableなど)でも失敗します。これらはコンテンツの編集では解消できません。生成された仕様やサードパーティ製の仕様を変更せずに済むよう、ソースのoverlaysにある OpenAPI Overlay で修正し、ソース側での修正を報告してください。Blume にジェネレーターがないcodeSamplesID(BLUME_OPENAPI_UNKNOWN_CODE_SAMPLE)は、代わりに設定から削除します。リダイレクトを追加した場合は、ビルド後にblume audit --only redirectsを実行してください。validateは、転送先が存在しないリダイレクト(blume.config.tsの該当行にあるBLUME_BROKEN_REDIRECT)には警告しますが、toが別のリダイレクトのfromである場合は受け入れます。そのため、各リダイレクトをビルド後にたどり、ループや連鎖を報告するのはauditだけです。以前の URL をすべて確認するには、blume devまたはblume previewにリクエストを送る(curl -sL。どちらもパターンを含むすべてのリダイレクトを適用し、ステータスも返します)か、dist/とリダイレクトルール(ホストアダプターが設定されていない場合はdist/blume-redirects.json、設定されている場合はホストの_redirectsまたはvercel.json)を確認します。以前の見出しアンカー: すべてのソースで見出し ID のスラッグ化方法が Blume と異なります。最初のビルド後にnode <skill>/scripts/pin-heading-ids.mjs --old <old site URL or its built-HTML dir>を実行します(ページを移動した場合は--map dist/blume-redirects.jsonを指定します。これはホストアダプターなしでビルドした場合に使用します。適用するには--write、リンクされている ID だけを固定するには--only-linkedを指定します)。0 件になるまで再ビルドしてください。サーバービルドではスクリプトがdist/clientを自動的に読み取ります(ReadMe と GitHub wiki では見出し ID がすでに Blume と一致するため、この処理は省略してください。ReadMe のハブはクロールをレート制限し、スクリプトは wiki のページを読み取れません)。残ったBLUME_BROKEN_ANCHORは以前のサイトでもすでに無効だったため、明らかなものはリンク先を変更し、それ以外はフラグメントを削除して報告してください。blume devを実行し、サイトを目視で確認します(blume dev/preview --port Nは N が使用中の場合、次に空いているポートに移動するため、URL をリクエストする前に表示されたLocal http://…の行を確認してください)。ナビゲーション構造、タブ、テーマ、レンダリングされたコンポーネントを確認します。- 移行の概要を作成します。次の内容を含めてください。移行したもの(設定、N ページ、ナビゲーション、API リファレンス)、削除したもの(ナビゲーションバーの CTA、カスタムテーマ、条件付きリダイレクト、対応するアイコンがないもの、未対応コンポーネント)、推奨する今後の対応(完全な制御には
blume eject、コンポーネントをプロジェクトに取り込んでカスタマイズするにはblume add)。
ドキュメント全文
マッピングの詳細は references/ にあります。ソースフレームワークごとに1つのファイル(mintlify.md、docusaurus.md、fumadocs.md、nextra.md、starlight.md、vitepress.md、vuepress.md、mkdocs.md、mdbook.md、docus.md、fern.md、gitbook.md、readme.md、redocly.md、docsify.md、jekyll.md、github-wiki.md)があり、ホストリポジトリとの統合(コンテンツレイアウトの検出、pnpm の minimumReleaseAge、凍結ロックファイルの再生成、Vercel モノレポのレシピ、Astro/Vite のパッチ)には monorepo.md を参照してください。Mintlify のアイコンとフロントマターの処理は、scripts/mintlify-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的、冪等。適用するには --write)。Docsify のコンテンツ処理は、scripts/docsify-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的、冪等。適用するには --write、pin-heading-ids.mjs 用に旧見出し ID を記録するには --snapshot <dir>、サイドバーのグループごとにフォルダーを作成してルートテーブルを生成するには --group-folders)。Fern の配置、フロントマター、コンポーネント、リダイレクトの処理は、scripts/fern-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的、冪等。適用するには --write、初回ビルド後に endpoints)。ReadMe のコンテンツ処理は、scripts/readme-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的、冪等。適用するには --write、ビルド後にエンドポイントのリダイレクトを行うには --routes <file>)。MkDocs のコンテンツ処理は、scripts/mkdocs-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的、冪等。適用するには --write)。Jekyll のコンテンツとナビゲーションの処理は、scripts/jekyll-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的。1回だけ実行され、jekyll-migration.json を書き込み、すでにファイルがあるフォルダーでは実行を拒否します。適用するには --write、URL とサイドバーには --old <build>、_config.yml にコールアウトが指定されていないサイトには --callouts)。GitHub wiki の処理は、scripts/github-wiki-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的、冪等。routes はルートテーブルを生成し、convert --write は適用し、check はビルドに対してテーブルと旧 URL を検証し、stubs は旧 wiki 用のリンクスタブを生成します)。Docus のコンテンツ処理は、scripts/docus-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的、冪等。適用するには --write)。VitePress のコンテンツ処理は、scripts/vitepress-codemod.mjs によって自動化されています(依存関係ゼロ、決定論的、冪等。適用するには --write、.html リダイレクト一覧には --redirects <old build>)。リダイレクト用の操作ルートは scripts/operation-routes.mjs から取得します(依存関係ゼロ、読み取り専用。ビルド済みの dist/ を読み取ります)。部分ファイルとルート外のインクルードは scripts/include-excerpts.mjs によって生成されます(依存関係ゼロ、決定論的。プロジェクトにコピーして、ビルドのたびに実行します)。旧見出し ID は scripts/pin-heading-ids.mjs によって固定されます(依存関係ゼロ。既定ではレポートを出力し、適用するには --write)。Blume の正式なドキュメントは、インストール済みパッケージの docs/ ディレクトリに同梱されています。リポジトリのルートにあるとは限りません。ワークスペースのモノレポ(特に pnpm)では、パッケージは依存元ワークスペースの node_modules 内にあります(例:apps/docs/node_modules/blume/docs)。依存元パッケージから node -e "console.log(require.resolve('blume/package.json'))" を実行すると、正確な場所が出力されます。(Blume 自体のリポジトリチェックアウトでは、ドキュメントのソースは apps/docs/content/docs です。)特に関連性の高いページは次のとおりです。
configuration/index.mdx—blume.config.tsのすべてのフィールド。content/navigation.mdx— サイドバー、タブ、セレクターのモデル。content/meta.mdx—meta.tsと表示モード。content/syntax.mdx— ディレクティブ、コード機能、数式。content/components.mdx— コンポーネントライブラリと API。content/frontmatter.mdx— 厳格なページスキーマ。