A modern, type-safe MDX content site built with Next.js 16, Velite, and Tailwind CSS. Perfect for blogs, documentation sites, and content-driven projects that need the power of React components within Markdown.
This starter template provides a complete foundation for building content-rich websites with MDX. It uses Velite for type-safe content management, ensuring your frontmatter and content structure are validated at build time. With Next.js App Router and React Server Components, you get optimal performance and SEO out of the box.
- Next.js 16 App Router - Built on the latest Next.js with React Server Components for optimal performance
- Type-Safe Content - Velite validates your MDX frontmatter and generates TypeScript types
- MDX Support - Write Markdown with embedded React components
- Syntax Highlighting - Beautiful code blocks with copy-to-clipboard functionality powered by Shiki
- Dark Mode - Automatic dark mode with system preference detection via next-themes
- Modern UI - Pre-configured Shadcn/UI components with Tailwind CSS
- SEO Optimized - Automatic sitemap and robots.txt generation
- TypeScript - Full type safety across your entire project
- File-Based Routing - Content folder structure maps directly to URL routes
Before you begin, ensure you have the following installed:
- Node.js 18.17 or later
- pnpm (recommended) or npm
# Clone the repository
git clone https://github.com/brijr/mdx.git my-mdx-site
cd my-mdx-site
# Or use as a GitHub template
# Click "Use this template" on GitHubpnpm installThis will install all required dependencies including Next.js, Velite, Tailwind CSS, and UI components.
pnpm devThis command does two things:
- Watches your
content/directory for changes and rebuilds with Velite - Starts the Next.js development server with Turbopack
Your site will be available at http://localhost:3000
pnpm buildThis processes your MDX content with Velite and builds an optimized production bundle.
pnpm startServes your production build locally.
mdx-starter/
├── app/ # Next.js app directory
│ ├── [...slug]/ # Dynamic route for all MDX pages
│ ├── api/ # API routes (e.g., bookmark metadata)
│ ├── layout.tsx # Root layout with theme provider
│ └── page.tsx # Homepage
├── components/
│ ├── markdown/ # MDX components (code blocks, media, etc.)
│ ├── posts/ # Post list and item components
│ ├── theme/ # Theme provider and toggle
│ └── ui/ # Shadcn UI components
├── content/ # Your MDX content goes here
│ └── **/*.mdx # All MDX files are auto-discovered
├── lib/ # Utility functions
├── public/ # Static assets
├── velite.config.ts # Velite configuration
├── next.config.mjs # Next.js configuration
└── tailwind.config.ts # Tailwind CSS configuration
Create MDX files anywhere in the content/ directory. The folder structure automatically determines your URLs:
content/
├── about.mdx → /about
├── blog/
│ ├── getting-started.mdx → /blog/getting-started
│ └── advanced-tips.mdx → /blog/advanced-tips
└── docs/
├── installation.mdx → /docs/installation
└── configuration.mdx → /docs/configuration
---
title: "Getting Started with MDX"
description: "Learn how to create your first MDX post"
date: "2025-01-09"
author: "Your Name"
tags: ["nextjs", "mdx", "tutorial"]
published: true
---
# Getting Started
This is your MDX content. You can use **markdown** syntax and React components!
## Code Example
\`\`\`typescript
const greeting = "Hello, MDX!";
console.log(greeting);
\`\`\`
Mix in React components for interactive content.All frontmatter fields are validated by Velite. Here's what you can use:
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | ✅ | Page title (max 99 characters) |
description |
string | ❌ | SEO description (max 999 characters) |
date |
ISO date | ✅ | Publication date (e.g., "2025-01-09") |
author |
string | ❌ | Author name |
tags |
string[] | ❌ | Array of tags for categorization |
published |
boolean | ❌ | Show/hide post (default: true) |
You can import and use React components directly in your MDX files:
import { Button } from '@/components/ui/button'
# My Page
Click this button:
<Button>Click Me</Button>- Create a new
.mdxfile in thecontent/directory - Add required frontmatter (title and date)
- Write your content using Markdown and React components
- The dev server will automatically reload with your changes
This starter includes Shadcn/UI. Add new components with:
npx shadcn@latest add [component-name]Edit velite.config.ts to customize your content schema:
const posts = defineCollection({
name: "Post",
pattern: "**/*.mdx",
schema: s.object({
// Add your custom fields here
customField: s.string().optional(),
})
});- Tailwind Config: Edit
tailwind.config.ts - Global Styles: Modify
app/globals.css - Theme Colors: Update CSS variables in
app/globals.css
Update site metadata in app/layout.tsx:
export const metadata = {
title: "Your Site Name",
description: "Your site description",
// ... other metadata
}- Click the button above or visit vercel.com/new
- Import your repository
- Vercel will auto-detect Next.js and configure build settings
- Deploy!
This is a standard Next.js application and can be deployed to any platform that supports Node.js:
- Netlify: Works with Next.js runtime
- Railway: Easy Node.js deployment
- Self-hosted: Use
pnpm buildandpnpm start
No environment variables are required for basic functionality. Add your own as needed in .env.local:
# Example
NEXT_PUBLIC_SITE_URL=https://yourdomain.com- Next.js 16 - React framework
- Velite - Type-safe content toolkit
- MDX - Markdown + JSX
- Tailwind CSS - Utility-first CSS
- Shadcn/UI - Re-usable component library
- next-themes - Dark mode
- Shiki - Syntax highlighting
- TypeScript - Type safety
pnpm dev # Start development server with Velite watch mode
pnpm build # Build for production
pnpm start # Start production server
pnpm lint # Run ESLintMIT License - see LICENSE for details
Made by Bridger Tower
Found an issue or have a question? Please open an issue on GitHub.