Overview
Learn how to manage content using Content Collections and Fumadocs.
The starter kit uses Content Collections for managing content and Fumadocs for rendering documentation. This provides a powerful, type-safe content management system that's easy to use and maintain.
Why Content Collections? Content Collections is a great alternative to headless CMS platforms such as Contentful or Prismic. It's powered by MDX, free, open-source, and saves content directly in your repository. This means your content is version-controlled and easy to manage.
Features
- Type-safe content - Full TypeScript support with automatic type generation
- MDX support - Write content using Markdown with React components
- Version control - Content is stored in your repository, making it easy to track changes
- Fast builds - Content is compiled at build time for optimal performance
- Developer-friendly - Edit content using your favorite code editor
- No database required - Content is stored as files, not in a database
Content Collections
Content Collections provides:
- Schema validation - Define schemas for your content using Zod
- Automatic type generation - TypeScript types are generated from your schemas
- Query API - Easy-to-use API for querying content
- Transform functions - Process and transform content during build
Fumadocs
Fumadocs provides:
- Beautiful UI - Pre-built documentation UI components
- Search - Full-text search across your documentation
- Dark mode - Automatic theme switching
- Responsive design - Mobile-friendly layouts
- Table of contents - Automatically generated from headings
Blog
Documentation
Configuration
Content Collections is configured in content-collections.ts. The starter kit includes multiple collections:
import { defineCollection, defineConfig } from '@content-collections/core';
import { compileMDX } from '@content-collections/mdx';
import { z } from 'zod';
// Blog posts collection
const posts = defineCollection({
name: 'posts',
directory: 'content/posts',
include: '**/*.{mdx,md}',
schema: z.object({
title: z.string(),
date: z.string(),
authorName: z.string(),
excerpt: z.string().optional(),
tags: z.array(z.string()),
published: z.boolean(),
content: z.string()
}),
transform: async (document, context) => {
const body = await compileMDX(context, document);
return {
...document,
body,
path: document._meta.path.replace(/\.mdx?$/, '')
};
}
});
export default defineConfig({
collections: [posts]
});Building Content
Content Collections are automatically built during the Next.js build process. During development, they are rebuilt when files change.
Querying Content
You can query content in your application:
import { allDocuments } from 'content-collections/generated';
export default function BlogPage() {
const posts = allDocuments('posts')
.filter((post) => post.published)
.sort((a, b) => {
const dateA = new Date(a.date);
const dateB = new Date(b.date);
return dateB.getTime() - dateA.getTime();
});
return (
<div>
{posts.map((post) => (
<article key={post.path}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
}Best Practices
- Organize content - Use clear directory structures
- Use schemas - Define schemas for type safety
- Version control - Commit content changes to git
- Test locally - Always preview content before publishing
- Use MDX components - Leverage React components in your content