---
title: Blume 2 へのアップグレード
description: >-
  1 つのコマンドで Blume 1 のサイトを Blume 2 に移行し、設定の変更ごとにこのガイドを参照してください。アップグレード全体を Claude Code や Codex に任せることもできます。
sidebar:
  label: Blume 2 へのアップグレード
  order: 2.5
---

Blume 2 で変わるのは設定だけで、コンテンツは変わりません。削除された `search.boost` フロントマターフィールドを設定しているページを除き（[フロントマター](#frontmatter) を参照）、Markdown や MDX のページを編集する必要はありません。以前は名前付きの文字列やキー付きのブロックで指定していた設定は、`blume/*` サブパスからインポートして呼び出す**アダプター**になりました。対象は検索プロバイダー、デプロイ先、コンテンツソース、API リファレンス、アナリティクス、Ask AI のバックエンドです。機械可読な設定は `ai` から新しい `agents` キーに移動しました。また、`components.ts` のオーバーライドはビルド前にチェックされるようになりました。ゼロコンフィグのサイトや、これらの設定をどれも使っていないサイトでは、バージョンを上げるだけで済みます。

## 1 つのコマンドでアップグレードする [#upgrade-with-one-command]

プロジェクト（`blume.config.ts` があるフォルダー）でアップグレードを実行します：

```package-install
npx blume@latest upgrade
```

このコマンドは `package.json` 内の `blume` を 2 に上げ、プロジェクトで使っているパッケージマネージャーでインストールします。その後、設定と `components.ts` が Blume 2 に対応しているかをチェックします。まだ必要な変更はすべて、ファイル、行、置き換え内容とともに一覧表示されます。削除された `blume build` フラグをまだ渡している `package.json` のスクリプトもここに含まれます。変更が残っている間は、コマンドは 0 以外の終了コードで終了します。設定も `blume` の依存関係もないフォルダーで実行した場合は、エラーで停止します。`blume` ではなく `npx blume@latest` で実行してください。このコマンドは Blume 2 に含まれているため、まだ 1 を使っているプロジェクトにはありません。pnpm 12 では、`pnpm dlx` の後に `--allow-build=esbuild` を追加してください。pnpm 12 は、承認されていない esbuild のインストールスクリプトを実行しないためです。

変更をコーディングエージェントに任せる場合は、`--claude` または `--codex` を追加します：

```package-install
npx blume@latest upgrade --claude
```

エージェントは、検出結果とこのガイドを読み込んだ状態で対話モードで起動します。各変更を適用し、`blume doctor` と `blume build` の両方が成功するまで実行を繰り返します。すべての編集はエージェント自身の権限フローを通るため、1 つずつ確認できます。インストールせずに `package.json` のバージョンだけを上げるには、`--no-install` を渡します。

以下のセクションでは、変更点を 1 つずつ説明します。手動でアップグレードするときや、エージェントが行った変更を確認するときに参照してください。

## 検索 [#search]

`search` には、`provider` 文字列と認証情報のブロックの代わりに、`blume/search` のアダプターを渡します。デフォルトのローカル検索は変更不要です。

```ts title="Blume 1"
export default defineConfig({
  search: {
    provider: "algolia",
    algolia: { appId: "APP_ID", indexName: "docs", searchApiKey: "SEARCH_KEY" },
  },
});
```

```ts title="Blume 2"
import { defineConfig } from "blume";
import { algolia } from "blume/search";

export default defineConfig({
  search: algolia({ appId: "APP_ID", indexName: "docs", apiKey: "SEARCH_KEY" }),
});
```

- Orama Cloud、Typesense、Mixedbread も同じように、それぞれ `oramaCloud()`、`typesense()`、`mixedbread()` に置き換えます。キーを受け取るアダプターでは、検索専用キーの名前はすべて `apiKey` です。`mixedbread()` はクエリをドキュメントサーバー上で実行するため、キーではなく `storeId` を受け取ります。それ以外のオプションはストア検索の呼び出しにそのまま渡され、`top_k` のデフォルトは 8 です。管理者キーはこれまでどおり環境変数（`ALGOLIA_ADMIN_API_KEY`、`ORAMA_PRIVATE_API_KEY`、`TYPESENSE_ADMIN_API_KEY`、`MIXEDBREAD_API_KEY`）に設定します。
- `provider: "pagefind"` は `pagefind()` に、`provider: "none"` は `search: false` になります。
- `popular` リンクや `indexing` オプションを残すには、アダプターを次のようにラップします: `search: { provider: algolia({ … }), popular: […] }`。

## デプロイ [#deployment]

`deployment` には、`adapter` と `output` フィールドの代わりに、`blume/deploy` のホストアダプターを渡します。`site` と `base` はアダプターのオプションに移動します。

```ts title="Blume 1"
export default defineConfig({
  deployment: {
    adapter: "vercel",
    output: "server",
    site: "https://docs.example.com",
  },
});
```

```ts title="Blume 2"
import { defineConfig } from "blume";
import { vercel } from "blume/deploy";

export default defineConfig({
  deployment: vercel({ site: "https://docs.example.com" }),
});
```

- `netlify()`、`cloudflare()`、`node()` も同じように使います。ホストアダプターを指定すると、サーバー出力に切り替わります。静的ビルドのまま、そのホスト向けのプラットフォームファイルも出力したい場合は、`output: "static"` を渡します。
- `site` または `base` だけを設定している場合は、変更不要です。`deployment: { site, base }` は今後も静的ビルドの書き方です。
- `redirects` には完全一致のパスを指定します。`from` や `to` に `:param` セグメントや `*` ワイルドカードが含まれていると、検証エラーになるようになりました。Blume 1 もパターンをサポートしておらず、ホストによって扱いが異なっていました。パターンを使うルールは、ホスト側の設定（`vercel.json`、`_redirects`）に移してください。
- `blume build` の `--adapter`、`--output`、`--base` フラグは廃止されました。いずれかを渡すとビルドはエラーで停止し、代わりに使う `deployment` の設定が表示されます。アダプターは `blume.config.ts` で明示的に指定してください。サーバー出力をプラットフォームの環境から推測する動作はなくなりました。

各アダプターのオプションについては、[デプロイ](/docs/deployment) を参照してください。

## コンテンツソース [#content-sources]

`content.sources` の各エントリーは、`{ type }` オブジェクトではなく `blume/sources` のアダプターで指定します。

```ts title="Blume 1"
export default defineConfig({
  content: {
    sources: [
      { type: "filesystem", root: "content" },
      {
        type: "github-releases",
        owner: "acme",
        repo: "sdk",
        prefix: "changelog",
      },
    ],
  },
});
```

```ts title="Blume 2"
import { defineConfig } from "blume";
import { filesystem, githubReleases } from "blume/sources";

export default defineConfig({
  content: {
    sources: [
      filesystem({ root: "content" }),
      githubReleases({ owner: "acme", repo: "sdk", prefix: "changelog" }),
    ],
  },
});
```

- `mdx-remote`、`sanity`、`notion`、`obsidian` は、それぞれ `mdxRemote()`、`sanity()`、`notion()`、`obsidian()` になります。その他のフィールドは、そのまま呼び出しの引数に移します。`{ type: "custom", source }` は `custom(source)` になります。
- `content.root`、`content.include`、`content.exclude` は、フォルダーが 1 つだけの場合の省略形として引き続き使えます。ただし、`sources` と一緒には使えなくなりました。併用している場合は、`filesystem()` エントリーに移してください。
- `githubReleases()` のリリースページは、1 つの言語でのみ公開されるようになりました。そのため多言語サイトでも、他のロケールの URL（`/de/changelog/…`）にはコピーされません。外部サイトがそれらのコピーにリンクしている場合は、デフォルトロケールのページへの [リダイレクト](/docs/deployment#redirects) を追加してください。

## API リファレンス [#api-references]

トップレベルの `openapi`、`asyncapi`、`graphql` ブロックは、`blume/reference` のアダプターを並べた 1 つの `reference` リストにまとめられます。`enabled` は削除してください。

```ts title="Blume 1"
export default defineConfig({
  openapi: { enabled: true, spec: "./openapi.yaml" },
  graphql: {
    enabled: true,
    spec: "./schema.graphql",
    endpoint: "https://api.example.com/graphql",
  },
});
```

```ts title="Blume 2"
import { defineConfig } from "blume";
import { graphql, openapi } from "blume/reference";

export default defineConfig({
  reference: [
    openapi({ spec: "./openapi.yaml" }),
    graphql({
      spec: "./schema.graphql",
      endpoint: "https://api.example.com/graphql",
    }),
  ],
});
```

- `asyncapi: { … }` は、オプションはそのままで `asyncapi({ … })` になります。
- AsyncAPI 1.x または 2.x の仕様は、これまでどおり自動的に 3.0 に変換されます。ただし、コンバーターはオプションのピア依存関係になったため、プロジェクトに `@asyncapi/converter` をインストールしてください。インストールしていない場合、ビルドはインストールコマンドを表示して失敗します。3.x の仕様では何もする必要はありません。
- `renderer: "scalar"` は、リスト内で独立した `scalar({ spec, theme, … })` エントリーになります。ブロックの `route` と `sources` はそのまま引き継ぎます。
- `enabled: false` のブロックは、リストに含めないだけで構いません。

## アナリティクス [#analytics]

`analytics` オブジェクトは、`blume/analytics` のアダプターを並べたリストになります。

```ts title="Blume 1"
export default defineConfig({
  analytics: {
    posthog: { key: "phc_…" },
    vercel: true,
  },
});
```

```ts title="Blume 2"
import { defineConfig } from "blume";
import { posthog, vercel } from "blume/analytics";

export default defineConfig({
  analytics: [posthog({ key: "phc_…" }), vercel()],
});
```

`cloudflare: { token }` は `cloudflare({ token })` になり、`scripts[]` の各エントリーは `script({ … })` になります。

## Ask AI

`ai.ask.provider` には `blume/ai` のアダプターを渡します。モデルと、それに関連するフィールドはアダプター側で指定します。

```ts title="Blume 1"
export default defineConfig({
  ai: {
    ask: {
      enabled: true,
      provider: "openrouter",
      model: "anthropic/claude-sonnet-4-5",
      reasoning: "none",
    },
  },
});
```

```ts title="Blume 2"
import { defineConfig } from "blume";
import { openrouter } from "blume/ai";

export default defineConfig({
  ai: {
    ask: {
      enabled: true,
      provider: openrouter({
        model: "anthropic/claude-sonnet-4-5",
        reasoning: "none",
      }),
    },
  },
});
```

使用できるアダプターは `gateway()`、`openrouter()`、`llmgateway()`、`inkeep()`、`openaiCompatible({ baseUrl, name, model, apiKeyEnv })` です。`model`、`apiKeyEnv`、`baseUrl`、`headers`、`reasoning` はアダプターに移動します。`enabled`、`instructions`、`retrieval`、`suggestions`、`cors`、`endpoint` は `ai.ask` に残ります。`provider` を指定しない場合は、これまでどおり AI Gateway が使われます。

## エージェントとその他の設定の移動 [#agents-and-other-config-moves]

機械可読な設定は `ai` から新しい `agents` キーに移動します。また、3 つの小さなフィールドの形式が変わります。

```ts title="Blume 1"
export default defineConfig({
  ai: { mcp: { enabled: true }, skills: "./skills" },
  lastModified: true,
  markdown: {
    codeBlocks: { theme: { light: "github-light", dark: "github-dark" } },
  },
  theme: { layout: "sidebar" },
});
```

```ts title="Blume 2"
export default defineConfig({
  agents: { mcp: { enabled: true }, skills: "./skills" },
  lastModified: "git",
  markdown: {
    code: { theme: { light: "github-light", dark: "github-dark" } },
  },
});
```

- `ai.api`、`ai.catalog`、`ai.llmsTxt`、`ai.markdownComponents`、`ai.mcp`、`ai.skills`、`ai.webBotAuth`、`ai.webmcp` は `agents.*` に移動します。`seo.agentReadability` と `seo.contentSignals` も同様です。`ai` に残るのは `ask` と `openInChat` だけです。
- `lastModified` には単純な値を指定します。`true` は `"git"` になり、`{ type: "git" }` や `{ type: "frontmatter" }` はその文字列だけを指定します。
- `markdown.codeBlocks` は `markdown.code` に統合されます。
- `theme.layout` は廃止されました。もともと参照されていなかったため、削除してください。

## フロントマター [#frontmatter]

フロントマターのフィールドが 1 つ廃止されました: `search.boost` です。Blume 1 では指定できましたが、検索では一度も使われておらず、指定してもページの順位は変わりませんでした。使用している箇所はすべて削除してください。削除していないページはヒント付きの検証エラーになり、`blume upgrade` はその箇所をファイルと行とともに一覧表示します。

## コンポーネントのオーバーライド [#component-overrides]

Blume 2 では、`components.ts` のすべてのエントリーを、実行時にフォールバックするのではなくビルド前にチェックします。`mdx` と `layout` の各エントリーには、インポートしたコンポーネント、パス文字列、`{ component, client, media }` オブジェクトのいずれかを指定する必要があります。また、`islands` グループは廃止されました。`client` モードを指定した `mdx` エントリーがアイランドになります。

```ts title="Blume 1"
import { defineComponents } from "blume";
import Counter from "./islands/Counter.tsx";

export default defineComponents({
  islands: { Counter },
});
```

```ts title="Blume 2"
import { defineComponents } from "blume";
import Counter from "./islands/Counter.tsx";

export default defineComponents({
  mdx: { Counter: { component: Counter, client: "visible" } },
});
```

インライン関数、`components.ts` 内で宣言したコンポーネント、スプレッド構文、計算されたキーは、`BLUME_COMPONENTS_INVALID` エラーになり、該当するエントリーが表示されます。コンポーネントを別のファイルに移し、そこからインポートしてください。`islands/` フォルダーの規約はこれまでどおり使えます。指定できる形式については、[カスタマイズ](/docs/configuration/customization) を参照してください。

## イジェクトしたアプリ [#ejected-apps]

Blume 1 で [イジェクト](/docs/configuration/customization#eject) したアプリは Blume CLI では実行されなくなりますが、`blume` パッケージには引き続き依存しています。ページは Blume のコンポーネントをインポートしています。`src/generated/` には、Blume 1 のジェネレーターが出力したサイトのスナップショットが入っています。さらに `astro build` は、検索インデックス、`llms.txt`、サイトマップを出力するために `blume.config.ts` を読み込み直します。この状態で `blume` だけを 2 に上げると、Blume 1 のスナップショットが、新しい形式を前提とする Blume 2 のコンポーネントと組み合わさってしまいます。そのため、以下の手順でイジェクトし直してください：

1. **Copy the project out**

    `astro.config.mjs`、`src/`、`.blume/`、`dist/`、`node_modules/`
    以外のすべてを空のフォルダーにコピーします。コンテンツ、`blume.config.ts`、`components.ts`、`islands/`、`public/`、リファレンスが読み込む仕様ファイル、`package.json`
    が対象です。イジェクトしたアプリには手を加えないでください。

2. **Upgrade the copy**

    コピー先で `npx blume@latest upgrade`
    を実行し、一覧表示された変更を適用して、`blume.config.ts` と `components.ts`
    を Blume 2 の形式にします。その後、`npx blume build`
    を実行し、イジェクトする前にサイトをビルドできることを確認します。

3. **Eject a fresh copy**

    コピー先で `npx blume eject --yes`
    を実行し、追加されたパッケージをインストールしてから、`npm run build`
    でビルドします。

4. **Carry your edits across**

    新しく生成された `astro.config.mjs` と `src/`
    を、イジェクト済みのアプリと差分比較し、自分で加えた変更を新しいファイルに移します。

新しいコピーの準備ができるまでは、イジェクト済みのアプリは Blume 1（`"blume": "^1"`）のままにしておき、そこで `blume upgrade` を実行しないでください。バージョンを上げない限り、何も変わりません。

## コマンドラインフラグ [#command-line-flags]

Blume 1 では、コマンドが受け付けないフラグは無視されていましたが、今後はすべての `blume` コマンドがエラーにします。不要なフラグやスペルミスのあるフラグを渡しているスクリプトや CI のステップは失敗し、認識されなかったフラグと、そのコマンドで使えるフラグが表示されます。`blume upgrade` が検出するのは、削除された 3 つの `blume build` フラグ（`--adapter`、`--output`、`--base`）だけです。他の `blume` スクリプトも確認してください。

## 作業を確認する [#check-your-work]

`blume upgrade` が変更の必要な箇所はもうないと報告したら、サイトのチェックを実行します：

```bash
npx blume doctor
npx blume build
```

すべての変更点と、それぞれの変更理由は [変更履歴](/changelog) に掲載しています。
