---
name: "mdx-content"
description: "Content schema design and MDX configuration patterns for knowledge bases. Use when designing content structure, configuring MDX processing, or setting up frontmatter schemas."
---
# MDX Content Management
## Content Schema Design
### Frontmatter Schema Pattern
Required fields for all content:
```yaml
---
title: string # Page title
description: string # Short description (for nav, search)
---
```
Common optional fields:
```yaml
date: date # Publication/update date
tags: string[] # Categorization
draft: boolean # Hide from production
order: number # Manual ordering
category: string # Primary category
```
### Type-Safe Schema Definition
```typescript
import { z } from 'zod';
const schema = z.object({
title: z.string(),
description: z.string(),
date: z.date().optional(),
tags: z.array(z.string()).optional(),
draft: z.boolean().default(false),
});
```
**Critical**: Validate at build time, not runtime. Catch schema errors early.
## MDX Plugin Configuration
### Essential Plugins
**Markdown processing (remark):**
- `remark-gfm`: GitHub Flavored Markdown (tables, task lists)
- `remark-frontmatter`: Parse YAML frontmatter
**HTML processing (rehype):**
- `rehype-slug`: Add IDs to headings (required for TOC)
- `rehype-autolink-headings`: Clickable heading links
- `rehype-pretty-code`: Syntax highlighting (Shiki-based)
### Minimal Config Example
```javascript
export default defineConfig({
markdown: {
remarkPlugins: [remarkGfm],
rehypePlugins: [
rehypeSlug,
[rehypeAutolinkHeadings, { behavior: 'wrap' }],
[rehypePrettyCode, { theme: 'github-dark' }],
],
},
});
```
## Content Organization Patterns
### Directory Structure
```
content/
docs/ # Main documentation
index.md
getting-started.md
api/ # Nested sections
auth.md
guides/ # Tutorials/guides
changelog.md # Special pages
```
**Routing**: Directory structure maps to URLs
- `docs/index.md` → `/docs`
- `docs/api/auth.md` → `/docs/api/auth`
### Collection Organization
Group related content into collections:
```typescript
export const collections = {
'docs': docsCollection,
'guides': guidesCollection,
'blog': blogCollection,
};
```
**Benefits**: Separate schemas, different processing, type safety per collection.
## Custom Components in MDX
### Providing Components
```typescript
// Make components available in MDX
const components = {
// Override defaults
h1: CustomH1,
code: CustomCode,
// Add custom components
Callout: CalloutComponent,
Tabs: TabsComponent,
};
```
### Common Patterns
**Callout/Alert:**
```mdx
Important information here
```
**Code with tabs:**
```mdx
...
...
```
## Syntax Highlighting
### Shiki Configuration
```javascript
[rehypePrettyCode, {
theme: 'github-dark',
keepBackground: false, // Use CSS custom properties
}]
```
**Theme switching**: Set `keepBackground: false`, control via CSS:
```css
pre {
background: var(--code-background);
}
```
### Code Block Features
```markdown
```js title="example.js" {3-5}
// Line 1
// Line 2
// Lines 3-5 highlighted
// ...
```
```
Supported: Line highlighting, titles, line numbers (framework-dependent).
## Content Queries
### Basic Filtering
```typescript
import { getCollection } from 'astro:content';
// Get published docs
const docs = await getCollection('docs', ({ data }) => {
return !data.draft;
});
// Sort by date
docs.sort((a, b) =>
b.data.date.getTime() - a.data.date.getTime()
);
```
### Navigation Generation
```typescript
// Generate nav from content
const nav = docs
.filter(doc => !doc.data.draft)
.map(doc => ({
label: doc.data.title,
href: `/docs/${doc.slug}`,
order: doc.data.order ?? 999,
}))
.sort((a, b) => a.order - b.order);
```
## Table of Contents Generation
### Extract Headings
```typescript
// From markdown AST or rendered HTML
function extractHeadings(content: string) {
const headings = [];
// Parse headings from content
return headings.map(h => ({
depth: h.depth,
text: h.text,
slug: h.slug,
}));
}
```
**Display**: Show h2 and h3 only, indent by depth.
## Validation Checklist
Before committing content schema:
- [ ] Required fields defined
- [ ] TypeScript types generated
- [ ] Validation runs at build time
- [ ] Example content validates
- [ ] Frontmatter documented for authors
- [ ] Collections organized logically
## Common Issues
**Frontmatter not parsing:**
- Ensure triple dashes `---` around YAML
- Check indentation (YAML is whitespace-sensitive)
- Validate against schema
**Custom components not rendering:**
- Verify component is provided to MDX
- Check import paths
- Ensure component is exported
**Syntax highlighting broken:**
- Verify plugin is configured
- Check language identifier is valid
- Ensure theme is loaded
## Content Authoring Guidelines
Document for content authors:
```markdown
## Content Guidelines
1. **Frontmatter**: Required fields: `title`, `description`
2. **Headings**: Start with h2 (h1 is title)
3. **Links**: Use relative paths: `./other-doc.md`
4. **Images**: Place in `src/assets/`, use relative paths
5. **Code blocks**: Include language identifier
```
## Decision Points
**Schema design:**
- What content types exist?
- What metadata does each need?
- How will content be filtered/sorted?
**MDX features:**
- Which custom components are needed?
- What markdown extensions are required?
- How will code blocks be styled?
**Organization:**
- How to structure directories?
- How to handle navigation?
- How to generate TOC?
Document decisions in CLAUDE.md under "Content Structure" section.