Content Management with MDX and Velite
Learn how to build a type-safe content management system using MDX and Velite
What is MDX?
MDX is a format that lets you write JSX directly in your markdown files. This means you can import and use React components within your content!
import { CustomComponent } from './components'
# My Blog Post
Here's some regular markdown content.
<CustomComponent>
And here's a React component!
</CustomComponent>
Why Velite?
Velite is a build-time content processor that gives you:
- Type safety with Zod schemas
- Auto-generated TypeScript types for your content
- Build-time validation to catch errors early
- MDX support out of the box
Velite processes your content during the build step, so there's no runtime overhead!
Setting Up Velite
First, install the required packages:
npm install velite zod
Then create a velite.config.ts file:
import { defineConfig, defineCollection, s } from 'velite'
const posts = defineCollection({
name: 'Post',
pattern: 'blog/**/*.mdx',
schema: s.object({
title: s.string(),
description: s.string(),
date: s.isodate(),
tags: s.array(s.string()).default([]),
body: s.mdx(),
}),
})
export default defineConfig({
collections: { posts },
})
Using Your Content
Once Velite processes your content, you can import it with full type safety:
import { posts } from '.velite'
export default function BlogPage() {
return (
<div>
{posts.map((post) => (
<article key={post.title}>
<h2>{post.title}</h2>
<p>{post.description}</p>
<time>{post.date}</time>
</article>
))}
</div>
)
}
TypeScript will know the exact shape of your content, giving you autocomplete and type checking!
Custom MDX Components
You can provide custom components to all your MDX files:
export function useMDXComponents(components) {
return {
Callout: MyCalloutComponent,
CodeBlock: MyCodeBlockComponent,
...components,
}
}
Conclusion
MDX + Velite provides a powerful, type-safe way to manage content in your Next.js application. It combines the simplicity of markdown with the power of React components.