# Mdx Content

> Content schema design and MDX configuration patterns for knowledge bases. Use when designing content structure, configuring MDX processing, or setting up frontmatter schemas.

- Skill: `majiayu000/mdx-content` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/mdx-content`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/mdx-content/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/mdx-content

---


# 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
<Callout type="warning">
Important information here
</Callout>
```

**Code with tabs:**
```mdx
<Tabs>
  <Tab label="JavaScript">...</Tab>
  <Tab label="TypeScript">...</Tab>
</Tabs>
```

## 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.

