Blog Configuration
How to configure blog posts with Content Collections, categories, and authors.
Blog posts in the Content Collections system can have multiple categories, authors, and related posts. Everything is type-safe and automatically validated.
Authors
Create Author Profiles
Authors are managed as separate content files in content/authors/
. Each author has their own MDX file with profile information.
Create an Author File
Create a new file in content/authors/
:
# Create author file
touch content/authors/john-doe.mdx
---
title: "John Doe"
description: "Senior Developer and Technical Writer"
avatar: "/_static/avatars/john-doe.jpg"
twitter: "johndoe"
---
# About John
John is a senior developer with 10+ years of experience in web development...
Author Schema
// Automatically generated types from Content Collections
interface Author {
title: string; // Author's display name
description?: string; // Short bio
avatar?: string; // Profile image path
twitter?: string; // Twitter username (without @)
slug: string; // Auto-generated from filename
body: { raw: string }; // Author's full bio in MDX
}
Using Authors in Blog Posts
Reference authors in your blog posts using their filename (without .mdx
):
---
title: "Deploying Next.js Apps"
description: "How to deploy your Next.js apps on Vercel."
image: "/_static/blog/blog-post-3.jpg"
date: "2024-01-15"
authors:
- john-doe # References content/authors/john-doe.mdx
- jane-smith # References content/authors/jane-smith.mdx
categories:
- education
related:
- server-client-components
- preview-mode-headless-cms
---
Accessing Author Data
import { allAuthors, allPosts } from "content-collections";
// Get author information for a post
function getPostAuthors(post: Post) {
return post.authors.map(authorSlug =>
allAuthors.find(author => author.slugAsParams === authorSlug)
).filter(Boolean);
}
Categories
Available Categories
Categories are defined in the Content Collections schema and are type-safe:
categories: z.array(z.enum(["news", "education"])).default(["news"])
Current available categories:
news
- Updates, announcements, company newseducation
- Tutorials, guides, educational content
Adding New Categories
To add new categories, update the schema in content-collections.ts
:
schema: z.object({
// ... other fields
categories: z.array(z.enum(["news", "education", "tutorial", "announcement"])).default(["news"]),
// ... other fields
}),
After updating the schema:
- Restart your development server
- Content Collections will validate all existing posts
- TypeScript will enforce the new category types
Using Categories in Blog Posts
Add categories to your blog posts in the frontmatter:
---
title: "Advanced Next.js Tutorial"
description: "Learn advanced Next.js patterns and techniques."
image: "/_static/blog/advanced-nextjs.jpg"
date: "2024-01-15"
authors:
- john-doe
- jane-smith
categories:
- education
- tutorial
related:
- server-client-components
- preview-mode-headless-cms
---
Category Features
- Multiple Categories: Posts can belong to multiple categories
- Type Safety: Categories are validated at build time
- Automatic Filtering: Easy to filter posts by category
- SEO Optimization: Categories are included in metadata
// Filter posts by category
const educationPosts = allPosts.filter(post =>
post.categories.includes("education")
);
// Get all unique categories
const allCategories = [...new Set(
allPosts.flatMap(post => post.categories)
)];
Related Posts
Each blog post can reference related posts using their slugs (filename without .mdx
):
---
title: "Deploying Next.js Apps"
description: "How to deploy your Next.js apps on Vercel."
image: "/_static/blog/blog-post-3.jpg"
date: "2024-01-15"
authors:
- john-doe
- jane-smith
categories:
- education
related:
- server-client-components # References content/blog/server-client-components.mdx
- preview-mode-headless-cms # References content/blog/preview-mode-headless-cms.mdx
- advanced-routing # References content/blog/advanced-routing.mdx
---
Accessing Related Posts
import { allPosts } from "content-collections";
function getRelatedPosts(post: Post) {
return post.related?.map(slug =>
allPosts.find(p => p.slugAsParams === slug)
).filter(Boolean) || [];
}
// Usage in component
const relatedPosts = getRelatedPosts(currentPost);
Complete Blog Post Example
---
title: "Complete Guide to Next.js 15"
description: "Everything you need to know about Next.js 15 features and improvements."
image: "/_static/blog/nextjs-15-guide.jpg"
date: "2024-01-15"
published: true
authors:
- john-doe
- jane-smith
categories:
- education
- tutorial
related:
- getting-started-nextjs
- advanced-routing
- performance-optimization
---
# Complete Guide to Next.js 15
This comprehensive guide covers all the new features in Next.js 15...
## Table of Contents
- [App Router Improvements](#app-router)
- [Turbopack Integration](#turbopack)
- [Performance Enhancements](#performance)
## App Router Improvements
Next.js 15 brings significant improvements to the App Router...
This creates a fully-featured blog post with:
- ✅ Type-safe frontmatter validated by Content Collections
- ✅ Multiple authors with profile links
- ✅ Categorization for content organization
- ✅ Related posts for better content discovery
- ✅ SEO optimization with proper metadata
- ✅ Rich content with MDX support