mcpField
C
content-collections

content-collections

github.com/jackspace開発1667 回インストール15 週間前に更新
リポジトリ

content-collections について

content-collections は、ローカルの Markdown と MDX ファイルを検証済みの型付き TypeScript データに変換します。コンテンツの多いサイト向けに、ビルド時のモジュール生成、スキーマ検証、変換処理を提供します。

主な機能

  1. 01Markdown と MDX の解析
  2. 02ビルド時のスキーマ検証
  3. 03型付き TypeScript モジュール生成
  4. 04コレクションの変換処理
  5. 05Vite プラグイン連携
  6. 06MDX コンパイル対応

活用シーン

  1. 01型付きブログ記事コレクションの構築
  2. 02ビルド時の frontmatter 検証
  3. 03Vite サイトでのローカルコンテンツ利用
  4. 04React での MDX コンテンツ表示

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jackspace/claudeskillz --skill content-collections

インストール後、Claude Code で/content-collectionsを入力して読み込まれたか確認します。

同梱ファイルREADME.mdSKILL.json

詳細

コンテンツコレクション

ステータス:本番環境で使用可能 ✅ 最終更新日:2025-11-07 依存関係:なし 最新バージョン:@content-collections/[email protected]、@content-collections/[email protected]、[email protected]


Content Collections とは?

Content Collections は、ローカルのコンテンツファイル(Markdown/MDX)を、ビルド時に自動検証される型安全な TypeScript データに変換します。

解決する問題:手動でのコンテンツ解析、型安全性の欠如、無効なフロントマターによるランタイムエラー。

仕組み:

  1. content-collections.ts でコレクションを定義します(名前、ディレクトリ、Zod スキーマ)
  2. CLI/プラグインがファイルシステムをスキャンし、フロントマターを解析して、スキーマに照らして検証します
  3. .content-collections/generated/ に TypeScript モジュールを生成します
  4. コレクションをインポートします:import { allPosts } from "content-collections"

最適な用途:ブログ、ドキュメントサイト、Cloudflare Workers、Vite、Next.js を使用するコンテンツ中心のアプリ。


クイックスタート(5 分)

1. 依存関係をインストールする
pnpm add -D @content-collections/core @content-collections/vite zod
2. TypeScript のパスエイリアスを設定する

tsconfig.json に追加します:

{
  "compilerOptions": {
    "paths": {
      "content-collections": ["./.content-collections/generated"]
    }
  }
}
  1. Vite プラグインを設定する

vite.config.ts に追加します:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import contentCollections from "@content-collections/vite";

export default defineConfig({
  plugins: [
    react(),
    contentCollections(), // MUST come after react()
  ],
});
4. .gitignore を更新する
.content-collections/
5. コレクション設定を作成する

プロジェクトのルートに content-collections.ts を作成します:

import { defineCollection, defineConfig } from "@content-collections/core";
import { z } from "zod";

const posts = defineCollection({
  name: "posts",
  directory: "content/posts",
  include: "*.md",
  schema: z.object({
    title: z.string(),
    date: z.string(),
    description: z.string(),
    content: z.string(),
  }),
});

export default defineConfig({
  collections: [posts],
});
6. コンテンツディレクトリを作成する
mkdir -p content/posts

content/posts/first-post.md を作成します:

---
title: My First Post
date: 2025-11-07
description: Introduction to Content Collections
---

# My First Post

Content goes here...
7. インポートして使用する
import { allPosts } from "content-collections";

console.log(allPosts); // Fully typed!

結果:自動補完、検証、HMR に対応した型安全なコンテンツを利用できます。


重要なルール

✅ 必ず行うこと:
  1. tsconfig.json にパスエイリアスを追加する - インポートを機能させるために必要です
  2. .content-collections を .gitignore に追加する - 生成ファイルはコミットしないでください
  3. Standard Schema バリデーターを使用する - Zod、Valibot、ArkType に対応しています
  4. スキーマに content フィールドを含める - フロントマターの解析に必要です
  5. 変換処理で compileMDX を await する - MDX のコンパイルは非同期です
  6. Vite では contentCollections() を react() の後に配置する - プラグインの順序が重要です
❌ 絶対にしないこと:
  1. .content-collections ディレクトリをコミットする - 常に生成されるため、コミットしないでください
  2. 標準以外のバリデーターを使用する - StandardSchema 仕様への対応が必要です
  3. 設定変更後に開発サーバーを再起動し忘れる - 新しいコレクションを認識させるために必要です
  4. 非同期処理で同期変換を使用する - 変換処理は非同期である必要があります
  5. パスエイリアスを二重にラップする - ./content-collections ではなく content-collections を使用してください
  6. 誤ったパッケージからインポートする - 設定には @content-collections/core、データには content-collections を使用します

既知の問題を防ぐ

問題 #1:モジュールが見つかりません:'content-collections'

エラー:Cannot find module 'content-collections' or its corresponding type declarations

原因:TypeScript のパスエイリアス設定がありません。

予防策:

tsconfig.json に追加します:

{
  "compilerOptions": {
    "paths": {
      "content-collections": ["./.content-collections/generated"]
    }
  }
}

VS Code で TypeScript サーバーを再起動します:Cmd+Shift+P → "TypeScript: Restart TS Server"

出典:よくあるユーザーエラー


問題 #2:Vite が連続して再起動する

エラー:開発サーバーが無限ループで再起動し続けます。

原因:Vite が .content-collections ディレクトリの変更を監視しており、再生成が引き起こされています。

予防策:

  1. .gitignore に追加します:
.content-collections/
  1. (問題が続く場合)vite.config.ts に追加します:
export default defineConfig({
  server: {
    watch: {
      ignored: ["**/.content-collections/**"],
    },
  },
});

出典:GitHub Issue #591(TanStack Start)


問題 #3:変換後の型が反映されない

エラー:TypeScript の型が変換後のドキュメントと一致しません。

原因:TypeScript は変換関数の戻り値の型を自動的に推論しません。

予防策:

変換処理の戻り値の型を明示的に指定します:

const posts = defineCollection({
  name: "posts",
  // ... schema
  transform: (post): PostWithSlug => ({ // Type the return!
    ...post,
    slug: post._meta.path.replace(/\.md$/, ""),
  }),
});

type PostWithSlug = {
  // ... schema fields
  slug: string;
};

出典:GitHub Issue #396


問題 #4:ファイル変更時にコレクションが更新されない

エラー:新しいコンテンツファイルがコレクションに表示されません。

原因:Glob パターンが一致していないか、開発サーバーの再起動が必要です。

予防策:

  1. Glob パターンがファイルと一致することを確認します:
include: "*.md"        // Only root files
include: "**/*.md"     // All nested files
include: "posts/*.md"  // Only posts/ folder
  1. 監視対象のパターン外に新しいファイルを追加した場合は、開発サーバーを再起動します
  2. ファイルが実際に保存されていることを確認します(エディターの問題に注意してください)

出典:よくあるユーザーエラー


Issue #5:Shiki による MDX の型エラー

エラー:esbuild errors with shiki langAlias またはコンパイルエラーが発生します。

原因:Shiki と Content Collections のバージョンに互換性がありません。

予防策:

互換性のあるバージョンを使用してください。

{
  "devDependencies": {
    "@content-collections/mdx": "^0.2.2",
    "shiki": "^1.0.0"
  }
}

Shiki をアップグレードする前に、ドキュメントで公式の互換性マトリクスを確認してください。

出典:GitHub Issue #598(Next.js 15)


Issue #6:MDX インポートでカスタムパスエイリアスが機能しない

エラー:@ エイリアスを使った MDX インポートを解決できません。

原因:MDX コンパイラーは tsconfig のパスエイリアスを認識しません。

予防策:

MDX インポートでは相対パスを使用してください。


import Component from "@/components/Component"


import Component from "../../components/Component"

または、files appender を設定してください(上級者向け。references/transform-cookbook.md を参照)。

出典:GitHub Issue #547


Issue #7:検証エラーメッセージがわかりにくい

エラー:「Expected string, received undefined」のような、わかりにくい Zod 検証エラーが発生します。

原因:Zod エラーはコンテンツのコンテキストに合わせてフォーマットされていません。

予防策:

スキーマにカスタムエラーメッセージを追加してください。

schema: z.object({
  title: z.string({
    required_error: "Title is required in frontmatter",
    invalid_type_error: "Title must be a string",
  }),
  date: z.string().refine(
    (val) => !isNaN(Date.parse(val)),
    "Date must be valid ISO date (YYYY-MM-DD)"
  ),
})

出典:GitHub Issue #403


Issue #8:Ctrl+C でプロセスが停止しない

エラー:開発プロセスが終了時にハングし、kill -9 が必要になります。

原因:ファイルウォッチャーが適切にクリーンアップされません。

予防策:

これはウォッチャーの既知の問題です。回避策は次のとおりです。

  1. ハングした場合は kill -9 <pid> を使用する
  2. より細かく制御するには、プラグインではなく content-collections watch を単独で使用する
  3. vite.config.ts にクリーンアップハンドラーを追加する(上級者向け)

出典:GitHub Issue #546


設定パターン

基本的なブログコレクション
import { defineCollection, defineConfig } from "@content-collections/core";
import { z } from "zod";

const posts = defineCollection({
  name: "posts",
  directory: "content/posts",
  include: "*.md",
  schema: z.object({
    title: z.string(),
    date: z.string(),
    description: z.string(),
    tags: z.array(z.string()).optional(),
    content: z.string(),
  }),
});

export default defineConfig({
  collections: [posts],
});

複数コレクションの設定
const posts = defineCollection({
  name: "posts",
  directory: "content/posts",
  include: "*.md",
  schema: z.object({
    title: z.string(),
    date: z.string(),
    description: z.string(),
    content: z.string(),
  }),
});

const docs = defineCollection({
  name: "docs",
  directory: "content/docs",
  include: "**/*.md", // Nested folders
  schema: z.object({
    title: z.string(),
    category: z.string(),
    order: z.number().optional(),
    content: z.string(),
  }),
});

export default defineConfig({
  collections: [posts, docs],
});

変換関数(計算フィールド)
const posts = defineCollection({
  name: "posts",
  directory: "content/posts",
  include: "*.md",
  schema: z.object({
    title: z.string(),
    date: z.string(),
    content: z.string(),
  }),
  transform: (post) => ({
    ...post,
    slug: post._meta.path.replace(/\.md$/, ""),
    readingTime: Math.ceil(post.content.split(/\s+/).length / 200),
    year: new Date(post.date).getFullYear(),
  }),
});

React コンポーネントを使用した MDX
import { compileMDX } from "@content-collections/mdx";

const posts = defineCollection({
  name: "posts",
  directory: "content/posts",
  include: "*.mdx",
  schema: z.object({
    title: z.string(),
    date: z.string(),
    content: z.string(),
  }),
  transform: async (post) => {
    const mdx = await compileMDX(post.content, {
      syntaxHighlighter: "shiki",
      shikiOptions: {
        theme: "github-dark",
      },
    });

    return {
      ...post,
      mdx,
      slug: post._meta.path.replace(/\.mdx$/, ""),
    };
  },
});

React コンポーネントとの統合

React でコレクションを使用する
import { allPosts } from "content-collections";

export function BlogList() {
  return (
    <ul>
      {allPosts.map((post) => (
        <li key={post._meta.path}>
          <h2>{post.title}</h2>
          <p>{post.description}</p>
          <time>{post.date}</time>
        </li>
      ))}
    </ul>
  );
}

MDX コンテンツをレンダリングする
import { MDXContent } from "@content-collections/mdx/react";

export function BlogPost({ post }: { post: { mdx: string } }) {
  return (
    <article>
      <MDXContent code={post.mdx} />
    </article>
  );
}

Cloudflare Workers へのデプロイ

Content Collections は、次の理由から Cloudflare Workers に最適です。

  • ビルド時のみ動作します(実行時のファイルシステムアクセスは不要です)
  • 静的な JavaScript モジュールを出力します
  • 生成されたコードに Node.js の依存関係はありません
デプロイパターン
Local Dev → content-collections build → vite build → wrangler deploy
wrangler.toml
name = "my-content-site"
compatibility_date = "2025-11-07"

[assets]
directory = "./dist"
binding = "ASSETS"
ビルドスクリプト

package.json:

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "deploy": "pnpm build && wrangler deploy"
  }
}

注:Vite プラグインが content-collections build を自動的に処理します。


バンドルされたリソースの使用

テンプレート(templates/)

コピーしてすぐに使える設定ファイルです。

  • content-collections.ts - 基本的なブログの設定
  • content-collections-multi.ts - 複数コレクションの設定
  • content-collections-mdx.ts - シンタックスハイライトを使用した MDX
  • tsconfig.json - TypeScript の完全な設定
  • vite.config.ts - Vite プラグインの設定
  • blog-post.md - コンテンツファイルの例
  • BlogList.tsx - React のリストコンポーネント
  • BlogPost.tsx - React の MDX レンダリングコンポーネント
  • wrangler.toml - Cloudflare Workers の設定
リファレンス(references/)

高度なトピックを詳しく解説するドキュメントです。

  • schema-patterns.md - よく使われる Zod スキーマのパターン
  • transform-cookbook.md - 変換関数のレシピ
  • mdx-components.md - MDX と React の統合
  • deployment-guide.md - Cloudflare Workers の設定

読み込みのタイミング:基本的な設定を超える高度なパターンが必要な場合、Claude がこれらを読み込みます。

スクリプト(scripts/)
  • init-content-collections.sh - 1 つのコマンドで自動セットアップ

依存関係

必須
{
  "devDependencies": {
    "@content-collections/core": "^0.12.0",
    "@content-collections/vite": "^0.2.7",
    "zod": "^3.23.8"
  }
}
オプション(MDX)
{
  "devDependencies": {
    "@content-collections/markdown": "^0.1.4",
    "@content-collections/mdx": "^0.2.2",
    "shiki": "^1.0.0"
  }
}

公式ドキュメント


パッケージのバージョン(2025-11-07 検証済み)

パッケージバージョンステータス
@content-collections/core0.12.0✅ 最新の安定版
@content-collections/vite0.2.7✅ 最新の安定版
@content-collections/mdx0.2.2✅ 最新の安定版
@content-collections/markdown0.1.4✅ 最新の安定版
zod3.23.8✅ 最新の安定版

トラブルシューティング

問題:TypeScript が 'content-collections' を見つけられない

解決策:tsconfig.json にパスエイリアスを追加し、TS サーバーを再起動します。


問題:Vite が再起動を繰り返す

解決策:.content-collections/ を .gitignore と Vite の監視対象から除外する設定に追加します。


問題:変更が反映されない

解決策:開発サーバーを再起動し、glob パターンを確認して、ファイルが保存されていることを確かめます。


問題:MDX のコンパイルエラー

解決策:Shiki のバージョンとの互換性を確認し、MDX の構文を検証します。


問題:バリデーションエラーの内容がわかりにくい

解決策:Zod スキーマにカスタムエラーメッセージを追加します。


セットアップの完全なチェックリスト

  • @content-collections/core と @content-collections/vite をインストールした
  • スキーマの検証用に zod をインストールした
  • tsconfig.json にパスエイリアスを追加した
  • vite.config.ts に contentCollections() を追加した(react() の後)
  • .content-collections/ を .gitignore に追加した
  • プロジェクトのルートに content-collections.ts を作成した
  • コンテンツディレクトリ(例:content/posts/)を作成した
  • Zod スキーマでコレクションを定義した
  • frontmatter を含む最初のコンテンツファイルを作成した
  • React コンポーネントでコレクションをインポートした
  • 型が機能することを確認した(自動補完)
  • ホットリロードをテストした(コンテンツファイルを変更)

質問や問題がありますか?

  1. 詳細な解説については references/ ディレクトリを確認してください
  2. tsconfig.json のパスエイリアスを確認してください
  3. Vite プラグインの順序を確認してください(react() の後)
  4. 上記の既知の問題を確認してください
  5. 公式ドキュメントを確認してください:https://www.content-collections.dev/docs

コメント