---
title: カスタムソース
description: >-
  custom() を使って任意のバックエンドを Blume に接続できます。ContentSource インターフェースを実装したオブジェクト、またはカスタムシリアライザーを設定した組み込みエンジンを渡します。
---

`ContentSource` インターフェースを実装したオブジェクトであれば、どれでも `custom()` に渡すことができます。カスタムシリアライザーを持つアダプターや組み込みではないバックエンドも、この方法で接続します。その際、それらの SDK がコアのインストールに含まれることはありません。

```ts blume.config.ts
import { defineConfig } from "blume";
import { custom, filesystem } from "blume/sources";
import { sanitySource } from "blume/sources/sanity.ts";

export default defineConfig({
  content: {
    sources: [
      filesystem({ root: "docs" }),
      custom(
        sanitySource({
          name: "guides",
          prefix: "guides",
          projectId: "abc123",
          dataset: "production",
          query: `*[_type == "guide"]`,
          // Map custom Portable Text blocks to Blume components
          serializers: {
            callout: (block) => `<Callout>${block.text}</Callout>`,
          },
        })
      ),
    ],
  },
});
```

上記の `sanitySource` のように Blume のエンジンファクトリーで構築したソースは、実行中のコマンドのコンテキストで再構築されます。そのため、組み込みアダプターと同様に、`--preview` 指定時には下書きを読み込み、スナップショットを `.blume/cache` に保持します。独自のソースでも、`withContext(ctx)` を実装し、そのコンテキストで再構築した自身を返せば、同じように動作させることができます。

`custom()` はオプションオブジェクトではなく `ContentSource` インスタンスを受け取ります。そのため、[共通オプション](/ja/docs/content/sources#adapters)の `prefix` や `pollInterval` を渡す場所はありません。`prefix` はソース自身がプロパティとして設定し、再取得の動作はソースの `watch` メソッドの実装に従います。また、`custom()` はプレーンなデータではなく稼働中のインスタンスを保持するため、独自のランタイム依存関係やシークレットを宣言しません。これらはインスタンス自身が管理します。

ローカルファイルを読み込むカスタムソースでは、各エントリーに `sourcePath` を、ソース自体に `contentRoot` を設定してください。`sourcePath` は診断メッセージでファイル名を示すために使われ、相対パスの画像もそのファイルの場所を基準に解決されます。`contentRoot` は、ページの日付を決める git `log` の対象範囲を限定します。`contentRoot` を設定しない場合、そのソースのページには git から取得される[「最終更新日」](/ja/docs/configuration#last-modified)が付きません。
