• ShipSaaSDocumentation
  • Introduction
  • Getting Started
    • Installation
    • Environment Setup
    • Database Setup
    • Development Guide
  • Database
    • Repository Pattern
    • Drizzle Queries
    • Migration Workflow
    • Drizzle Studio
    • Best Practices
  • File Management
    • File Upload Component
    • Server Actions
    • Storage Configuration
  • Authentication Methods
    • Credentials Authentication
    • Magic Link Authentication
    • Two-Factor Authentication (2FA)
    • Social Authentication
    • API Keys & Bearer Tokens
    • Organizations (Multi-tenant)
  • Authorization & Permissions
    • Roles & Hierarchy
    • Route Protection
    • API Protection
    • CASL Permissions
  • Email & Notifications
    • Resend Setup
    • React Email Templates
    • Notification System
    • Email Workflows
    • Customization & Extension
  • Stripe & Payments
    • Stripe Setup
    • Better Auth Integration
    • Checkout Methods
    • Subscription Management
    • Admin Dashboard
    • Webhook Events
  • Architecture & Development
    • Presentation Layer
    • Service Layer
    • Persistence Layer
    • Helpers Architecture
    • Project Structure
    • Development Workflow
  • Testing
    • General Testing
    • Unit Testing
    • UI Component Testing
    • Repository Testing
    • Service Testing
    • End-to-End Testing
  • Deployment
    • Vercel Deployment
    • GitHub Actions CI/CD
    • Database Backup & Restore
    • Database Migrations
    • Troubleshooting Deployment
  • AI Agents Integration
  • Blog Management
    • Blog Setup
    • MDX Blog
    • Database Blog
  • Async Tasks
    • Setup
    • Email Workflows
    • Payment Processing
    • Maintenance Jobs
  1. Documentation
  2. Blog Management
  3. MDX Blog
Buydocschangelogsdemocommunity

MDX Blog

PreviousBlog SetupNextDatabase Blog
On this page
File StructureCreating MDX ContentAvailable ComponentsContent ManagementFile NamingContent OrganizationDevelopment WorkflowSEO OptimizationPerformance FeaturesAdvanced FeaturesCustom ComponentsCode HighlightingContent MigrationExport from Database BlogImport to Database Blog

Create and manage static blog content using MDX files with React components.

Developer-Friendly: The MDX blog system is perfect for technical documentation, tutorials, and content that benefits from interactive React components.

File Structure

The MDX blog uses a simple file-based structure:

src/app/[locale]/(public)/blog/mdx/
├── _files/
│   ├── introduction-next-js.mdx
│   ├── tailwind-css-v4.mdx
│   ├── guide-react-19.mdc
│   └── sample.mdx
├── [slug]/
│   └── page.tsx
└── page.tsx

Key Locations:

  • Content Files: _files/ directory contains all MDX content
  • Routing: Dynamic [slug] route renders individual posts
  • Index: page.tsx displays list of all MDX posts

Creating MDX Content

1

Create MDX File

Create a new .mdx or .mdc file in the _files/ directory:

bash
# Navigate to the MDX files directory
cd src/app/[locale]/(public)/blog/mdx/_files/

# Create a new blog post
touch my-awesome-post.mdx
2

Add Frontmatter

Start your MDX file with YAML frontmatter at the top of the file.

Frontmatter Fields:

  • title - Post title (required)
  • description - Meta description for SEO
  • publishedAt - Publication date
  • readTime - Estimated reading time
  • category - Content category
  • tags - Array of tags
  • author - Content author
3

Write Content

Add your content using Markdown and React components. You can use:

  • Headings with # ## ###
  • Callout components for important information
  • Tabs and Tab components for organized content
  • Code blocks with syntax highlighting
  • Interactive buttons and other React components
  • Lists, tables, and standard markdown

Available Components

The MDX blog supports all documentation components:

markdown
<Callout type="info">
  Information callout with blue styling
</Callout>

<Callout type="warning">
  Warning callout with yellow styling
</Callout>

<Callout type="error">
  Error callout with red styling
</Callout>

<Callout type="success">
  Success callout with green styling
</Callout>
markdown
<Tabs defaultValue="option1">
  <Tab value="option1" label="Option 1">
    Content for the first tab
  </Tab>
  <Tab value="option2" label="Option 2">
    Content for the second tab
  </Tab>
</Tabs>
markdown
<Steps>
<Step title="First Step">
  Instructions for the first step
</Step>
<Step title="Second Step">
  Instructions for the second step
</Step>
</Steps>
```typescript title="example.ts"
interface User {
  id: string
  name: string
  email: string
}

const createUser = (data: User) => {
  // Implementation here
}
```

Content Management

File Naming

Use descriptive, URL-friendly filenames:

bash
# Good examples
introduction-to-react.mdx
nextjs-performance-tips.mdx
typescript-best-practices.mdx

# Avoid
My Post!.mdx
post-1.mdx
untitled.mdx

Content Organization

Organize content logically:

1

Categories

Use consistent categories in frontmatter:

  • "Development" - Technical content
  • "Tutorial" - Step-by-step guides
  • "News" - Updates and announcements
  • "Tips" - Quick tips and tricks
2

Tags

Use specific, searchable tags like: ["nextjs", "react", "typescript", "performance"]

3

Publishing Dates

Use consistent date format: "2024-01-15" (YYYY-MM-DD format)

Development Workflow

1

Create Content

bash
# Create new MDX file
cd src/app/[locale]/(public)/blog/mdx/_files/
touch new-post.mdx

# Add frontmatter and content
# Save the file
2

Preview Content

bash
# Start development server
pnpm dev

# Navigate to MDX blog
open http://localhost:3000/blog/mdx

# Click on your new post to preview
3

Test Components

Ensure your React components work correctly:

# Test interactive components
<Button onClick={() => console.log('Clicked!')}>
  Test Button
</Button>

# Test data display
<Tabs defaultValue="test">
  <Tab value="test" label="Test">
    This is a test tab
  </Tab>
</Tabs>
4

Commit Changes

bash
# Add to git
git add .
git commit -m "Add new blog post: Getting Started with Next.js"
git push origin main

# Deploy automatically triggers

SEO Optimization

MDX posts automatically generate SEO metadata:

1

Meta Tags

Generated from frontmatter:

typescript
// Automatic generation
<meta name="title" content="Getting Started with Next.js 15" />
<meta name="description" content="Complete guide to the latest Next.js features" />
<meta property="og:title" content="Getting Started with Next.js 15" />
<meta property="og:description" content="Complete guide to..." />
<meta name="twitter:title" content="Getting Started with Next.js 15" />
2

Structured Data

JSON-LD structured data for articles:

json
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Getting Started with Next.js 15",
  "description": "Complete guide to the latest Next.js features",
  "datePublished": "2024-01-15",
  "author": {
    "@type": "Person",
    "name": "Tech Team"
  }
}

Performance Features

The MDX blog is optimized for performance:

Build Time

  • • Static generation at build time
  • • Automatic code splitting
  • • Optimized bundle sizes
  • • Component tree shaking

Runtime

  • • Fast page loads
  • • CDN-friendly static assets
  • • Minimal JavaScript
  • • Progressive enhancement

Advanced Features

Custom Components

Create custom components for your MDX content:

1

Create Component

tsx
// components/mdx/demo-component.tsx
interface DemoProps {
  title: string
  children: React.ReactNode
}

export function Demo({ title, children }: DemoProps) {
  return (
    <div className="p-4 border rounded-lg bg-muted">
      <h3 className="font-semibold mb-2">{title}</h3>
      {children}
    </div>
  )
}
2

Import in MDX

import { Demo } from '@/components/mdx/demo-component'

# My Blog Post

<Demo title="Interactive Demo">
  This is a custom component with interactive content.
</Demo>

Code Highlighting

Syntax highlighting is built-in:

```typescript title="user-service.ts" {2,5-7}
export interface User {
  id: string          // highlighted line
  name: string
  email: string
  createdAt: Date     // highlighted lines
  updatedAt: Date     // highlighted lines
  isActive: boolean   // highlighted lines
}
```

Content Migration

Export from Database Blog

Convert database posts to MDX:

typescript
// Export database post to MDX
export async function exportToMDX(postId: string) {
  const post = await getPostById(postId)

  const frontmatter = {
    title: post.title,
    description: post.description,
    publishedAt: post.publishedAt.toISOString().split('T')[0],
    category: post.category?.name,
    tags: post.hashtags.map(h => h.name)
  }

  const mdxContent = `---
${yaml.stringify(frontmatter)}---

${post.content}
`

  fs.writeFileSync(`_files/${post.slug}.mdx`, mdxContent)
}

Import to Database Blog

Convert MDX files to database posts (see Database Blog documentation).

MDX Blog Ready! Your static blog system is now set up. Create .mdx files in the _files/ directory and they'll automatically appear on your blog at /blog/mdx.