MCP HubMCP Hub
返回技能列表

content-collections

jezweb
更新于 Today
3711 次查看
33
4
33
在 GitHub 上查看
wordreacttestingautomationdesigndata

关于

This skill provides a production-tested setup for Content Collections, a TypeScript-first tool that transforms Markdown/MDX files into type-safe data collections with Zod validation. Use it when building blogs, documentation sites, or content-heavy Vite + React applications to ensure type safety and automatic content validation. It covers everything from Vite plugin configuration and MDX compilation to deployment optimization and schema validation.

快速安装

Claude Code

推荐
插件命令推荐
/plugin add https://github.com/jezweb/claude-skills
Git 克隆备选方式
git clone https://github.com/jezweb/claude-skills.git ~/.claude/skills/content-collections

在 Claude Code 中复制并粘贴此命令以安装该技能

技能文档

Content Collections

Status: Production Ready ✅ Last Updated: 2025-11-07 Dependencies: None Latest Versions: @content-collections/[email protected], @content-collections/[email protected], [email protected]


What is Content Collections?

Content Collections transforms local content files (Markdown/MDX) into type-safe TypeScript data with automatic validation at build time.

Problem it solves: Manual content parsing, lack of type safety, runtime errors from invalid frontmatter.

How it works:

  1. Define collections in content-collections.ts (name, directory, Zod schema)
  2. CLI/plugin scans filesystem, parses frontmatter, validates against schema
  3. Generates TypeScript modules in .content-collections/generated/
  4. Import collections: import { allPosts } from "content-collections"

Perfect for: Blogs, documentation sites, content-heavy apps with Cloudflare Workers, Vite, Next.js.


Quick Start (5 Minutes)

1. Install Dependencies

pnpm add -D @content-collections/core @content-collections/vite zod

2. Configure TypeScript Path Alias

Add to tsconfig.json:

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

  1. Configure Vite Plugin

Add to 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. Update .gitignore

.content-collections/

5. Create Collection Config

Create content-collections.ts in project root:

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. Create Content Directory

mkdir -p content/posts

Create 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 and Use

import { allPosts } from "content-collections";

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

Result: Type-safe content with autocomplete, validation, and HMR.


Critical Rules

✅ Always Do:

  1. Add path alias to tsconfig.json - Required for imports to work
  2. Add .content-collections to .gitignore - Generated files shouldn't be committed
  3. Use Standard Schema validators - Zod, Valibot, ArkType supported
  4. Include content field in schema - Required for frontmatter parsing
  5. Await compileMDX in transforms - MDX compilation is async
  6. Put contentCollections() after react() in Vite - Plugin order matters

❌ Never Do:

  1. Commit .content-collections directory - Always generated, never committed
  2. Use non-standard validators - Must support StandardSchema spec
  3. Forget to restart dev server after config changes - Required for new collections
  4. Use sync transforms with async operations - Transform must be async
  5. Double-wrap path alias - Use content-collections not ./content-collections
  6. Import from wrong package - @content-collections/core for config, content-collections for data

Known Issues Prevention

Issue #1: Module not found: 'content-collections'

Error: Cannot find module 'content-collections' or its corresponding type declarations

Why it happens: Missing TypeScript path alias configuration.

Prevention:

Add to tsconfig.json:

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

Restart TypeScript server in VS Code: Cmd+Shift+P → "TypeScript: Restart TS Server"

Source: Common user error


Issue #2: Vite Constant Restart Loop

Error: Dev server continuously restarts, infinite loop.

Why it happens: Vite watching .content-collections directory changes, which triggers regeneration.

Prevention:

  1. Add to .gitignore:
.content-collections/
  1. Add to vite.config.ts (if still happening):
export default defineConfig({
  server: {
    watch: {
      ignored: ["**/.content-collections/**"],
    },
  },
});

Source: GitHub Issue #591 (TanStack Start)


Issue #3: Transform Types Not Reflected

Error: TypeScript types don't match transformed documents.

Why it happens: TypeScript doesn't automatically infer transform function return type.

Prevention:

Explicitly type your transform return:

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;
};

Source: GitHub Issue #396


Issue #4: Collection Not Updating on File Change

Error: New content files not appearing in collection.

Why it happens: Glob pattern doesn't match, or dev server needs restart.

Prevention:

  1. Verify glob pattern matches your files:
include: "*.md"        // Only root files
include: "**/*.md"     // All nested files
include: "posts/*.md"  // Only posts/ folder
  1. Restart dev server after adding new files outside watched patterns
  2. Check file actually saved (watch for editor issues)

Source: Common user error


Issue #5: MDX Type Errors with Shiki

Error: esbuild errors with shiki langAlias or compilation failures.

Why it happens: Version incompatibility between Shiki and Content Collections.

Prevention:

Use compatible versions:

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

Check official compatibility matrix in docs before upgrading Shiki.

Source: GitHub Issue #598 (Next.js 15)


Issue #6: Custom Path Aliases in MDX Imports Fail

Error: MDX imports with @ alias don't resolve.

Why it happens: MDX compiler doesn't respect tsconfig path aliases.

Prevention:

Use relative paths in MDX imports:

<!-- ❌ Won't work -->
import Component from "@/components/Component"

<!-- ✅ Works -->
import Component from "../../components/Component"

Or configure files appender (advanced, see references/transform-cookbook.md).

Source: GitHub Issue #547


Issue #7: Unclear Validation Error Messages

Error: Cryptic Zod validation errors like "Expected string, received undefined".

Why it happens: Zod errors aren't formatted for content context.

Prevention:

Add custom error messages to schema:

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)"
  ),
})

Source: GitHub Issue #403


Issue #8: Ctrl+C Doesn't Stop Process

Error: Dev process hangs on exit, requires kill -9.

Why it happens: File watcher not cleaning up properly.

Prevention:

This is a known issue with the watcher. Workarounds:

  1. Use kill -9 <pid> when it hangs
  2. Use content-collections watch separately (not plugin) for more control
  3. Add cleanup handler in vite.config.ts (advanced)

Source: GitHub Issue #546


Configuration Patterns

Basic Blog Collection

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],
});

Multi-Collection Setup

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],
});

Transform Functions (Computed Fields)

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(),
  }),
});

MDX with React Components

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 Component Integration

Using Collections in 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>
  );
}

Rendering MDX Content

import { MDXContent } from "@content-collections/mdx/react";

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

Cloudflare Workers Deployment

Content Collections is perfect for Cloudflare Workers because:

  • Build-time only (no runtime filesystem access)
  • Outputs static JavaScript modules
  • No Node.js dependencies in generated code

Deployment Pattern

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"

Build Script

package.json:

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

Note: Vite plugin handles content-collections build automatically!


Using Bundled Resources

Templates (templates/)

Copy-paste ready configuration files:

  • content-collections.ts - Basic blog setup
  • content-collections-multi.ts - Multiple collections
  • content-collections-mdx.ts - MDX with syntax highlighting
  • tsconfig.json - Complete TypeScript config
  • vite.config.ts - Vite plugin setup
  • blog-post.md - Example content file
  • BlogList.tsx - React list component
  • BlogPost.tsx - React MDX render component
  • wrangler.toml - Cloudflare Workers config

References (references/)

Deep-dive documentation for advanced topics:

  • schema-patterns.md - Common Zod schema patterns
  • transform-cookbook.md - Transform function recipes
  • mdx-components.md - MDX + React integration
  • deployment-guide.md - Cloudflare Workers setup

When to load: Claude should load these when you need advanced patterns beyond basic setup.

Scripts (scripts/)

  • init-content-collections.sh - One-command automated setup

Dependencies

Required

{
  "devDependencies": {
    "@content-collections/core": "^0.12.0",
    "@content-collections/vite": "^0.2.7",
    "zod": "^3.23.8"
  }
}

Optional (MDX)

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

Official Documentation


Package Versions (Verified 2025-11-07)

PackageVersionStatus
@content-collections/core0.12.0✅ Latest stable
@content-collections/vite0.2.7✅ Latest stable
@content-collections/mdx0.2.2✅ Latest stable
@content-collections/markdown0.1.4✅ Latest stable
zod3.23.8✅ Latest stable

Troubleshooting

Problem: TypeScript can't find 'content-collections'

Solution: Add path alias to tsconfig.json, restart TS server.


Problem: Vite keeps restarting

Solution: Add .content-collections/ to .gitignore and Vite watch ignore.


Problem: Changes not reflecting

Solution: Restart dev server, verify glob pattern, check file saved.


Problem: MDX compilation errors

Solution: Check Shiki version compatibility, verify MDX syntax.


Problem: Validation errors unclear

Solution: Add custom error messages to Zod schema.


Complete Setup Checklist

  • Installed @content-collections/core and @content-collections/vite
  • Installed zod for schema validation
  • Added path alias to tsconfig.json
  • Added contentCollections() to vite.config.ts (after react())
  • Added .content-collections/ to .gitignore
  • Created content-collections.ts in project root
  • Created content directory (e.g., content/posts/)
  • Defined collection with Zod schema
  • Created first content file with frontmatter
  • Imported collection in React component
  • Verified types work (autocomplete)
  • Tested hot reloading (change content file)

Questions? Issues?

  1. Check references/ directory for deep dives
  2. Verify path alias in tsconfig.json
  3. Check Vite plugin order (after react())
  4. Review known issues above
  5. Check official docs: https://www.content-collections.dev/docs

GitHub 仓库

jezweb/claude-skills
路径: skills/content-collections
aiautomationclaude-codeclaude-skillscloudflarereact

相关推荐技能

polymarket

这个Claude Skill为开发者提供完整的Polymarket预测市场开发支持,涵盖API调用、交易执行和市场数据分析。关键特性包括实时WebSocket数据流,可监控实时交易、订单和市场动态。开发者可用它构建预测市场应用、实施交易策略并集成实时市场预测功能。

查看技能

sglang

SGLang是一个专为LLM设计的高性能推理框架,特别适用于需要结构化输出的场景。它通过RadixAttention前缀缓存技术,在处理JSON、正则表达式、工具调用等具有重复前缀的复杂工作流时,能实现极速生成。如果你正在构建智能体或多轮对话系统,并追求远超vLLM的推理性能,SGLang是理想选择。

查看技能

evaluating-llms-harness

测试

该Skill通过60+个学术基准测试(如MMLU、GSM8K等)评估大语言模型质量,适用于模型对比、学术研究及训练进度追踪。它支持HuggingFace、vLLM和API接口,被EleutherAI等行业领先机构广泛采用。开发者可通过简单命令行快速对模型进行多任务批量评估。

查看技能

cloudflare-turnstile

这个Skill提供完整的Cloudflare Turnstile集成知识,用于在表单、登录页面和API端点中实现无验证码的机器人防护。它支持React/Next.js/Hono等框架集成,涵盖令牌验证、错误代码调试和端到端测试等场景。通过运行后台不可见挑战,在保持用户体验的同时有效阻止自动化流量和垃圾信息。

查看技能