)
}
```
--------------------------------
### MDX with custom component example
Source: https://github.com/mquintal/react-router-mdx/blob/master/README.md
Example of an MDX file that uses a custom YouTube component.
```mdx
---
title: hello world title
---
# hello world
This is a hello World mdx file
```
--------------------------------
### Basic loadAllMdx Usage Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/server.md
Example of using loadAllMdx to fetch metadata for all MDX files.
```typescript
import { loadAllMdx } from 'react-router-mdx/server'
export async function loader() {
const allPosts = await loadAllMdx()
return { posts: allPosts }
// Returns:
// [
// { path: 'posts/hello-world.mdx', slug: 'hello-world', title: 'Hello World', date: '2024-01-01' },
// { path: 'posts/my-post.mdx', slug: 'my-post', title: 'My Post', date: '2024-01-02' }
// ]
}
```
--------------------------------
### Advanced Configuration with Plugins
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Example of advanced configuration using plugins for remark and rehype, and setting up SSR and prerendering.
```typescript
// react-router.config.ts
import { init } from 'react-router-mdx/server'
const mdx = init({
path: 'content/posts',
alias: 'blog'
})
export default {
ssr: true,
async prerender() {
return ["/", "/blog", ...(await mdx.paths())]
}
}
```
```typescript
// app/routes/post.tsx
import { loadMdx } from 'react-router-mdx/server'
import { useMdxComponent, useMdxAttributes } from 'react-router-mdx/client'
import remarkGfm from 'remark-gfm'
import rehypeHighlight from 'rehype-highlight'
import type { Route } from './+types/post'
export async function loader({ request }: Route.LoaderArgs) {
return await loadMdx(request, {
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypeHighlight]
})
}
export default function Post() {
const Component = useMdxComponent()
const { title, date } = useMdxAttributes()
return (
{title}
)
}
```
--------------------------------
### Simple Blog - app/routes.tsx
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Route definitions for a simple blog setup.
```typescript
// app/routes.tsx
import { index, route } from "@react-router/dev/routes"
import { routes } from 'react-router-mdx/server'
export default [
index("routes/home.tsx"),
route("/blog", "routes/blog-index.tsx"),
...routes("./routes/post.tsx")
]
```
--------------------------------
### URL to File Path Transformation Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/architecture.md
Illustrates how a URL is converted back into a file path.
```text
Input URL: https://example.com/blog/hello-world
Paths: ['posts']
Aliases: ['blog']
Transformation:
1. Extract URL path: /blog/hello-world
2. Find matching alias: blog matches index 0
3. Get corresponding path: posts (index 0)
4. Extract slug: hello-world
5. Construct file path: {cwd}/posts/hello-world.mdx
```
--------------------------------
### Nested MDX Files
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Example of handling nested MDX files and deriving information from the slug.
```typescript
import { useMdxAttributes } from 'react-router-mdx/client'
export default function Post() {
const attributes = useMdxAttributes()
// For /posts/2024/january
// You can derive the year and month from the slug if needed
const slug = useParams().slug // "2024/january"
const [year, month] = slug.split('/')
return {/* ... */}
}
```
--------------------------------
### MDX File Location - Blog Posts
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Example of organizing MDX files for a blog post collection.
```plaintext
posts/
├── 2024-01-01-hello-world.mdx
├── 2024-01-15-react-tips.mdx
└── 2024-02-01-typescript-guide.mdx
```
--------------------------------
### LoadData Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/types.md
Example usage of LoadData in a route loader.
```typescript
// In route loader
const data = await loadMdx(request)
// data: LoadData = {
// __raw: "export const metadata = {...}; export default function MDXContent(props) {...}",
// attributes: { title: 'My Post', date: '2024-01-01', author: 'Jane' }
// }
```
--------------------------------
### Create MDX files
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Example of a basic MDX file with frontmatter.
```mdx
---
title: Hello World
date: 2024-01-01
author: Jane Doe
---
# Hello World
This is my first post.
```
--------------------------------
### getAttributes Example Usage (No Frontmatter)
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/utilities.md
Example of using getAttributes when MDX content has no frontmatter.
```typescript
const content = `# Hello World without frontmatter`
const attrs = getAttributes(content)
// Returns: {} (empty object)
```
--------------------------------
### MDX File Location - Documentation
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Example of organizing MDX files for a documentation collection.
```plaintext
docs/
├── getting-started.mdx
├── installation.mdx
├── api/
│ ├── overview.mdx
│ └── functions.mdx
└── guides/
└── advanced.mdx
```
--------------------------------
### Example 1: Custom Route Generation
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/utilities.md
Generates custom routes by listing MDX files and transforming their paths.
```typescript
import { listMdxFilesSync, transformFilePathToUrlPath } from 'react-router-mdx/server/utils'
import { route } from '@react-router/dev/routes'
const customRoutes = () => {
const paths = ['posts']
const files = listMdxFilesSync(paths)
return files[0].map(filePath => {
const urlPath = transformFilePathToUrlPath(filePath, paths[0])
// Add custom metadata
return route(urlPath, 'routes/post.tsx', {
id: urlPath,
handle: {
breadcrumb: urlPath.split('/').pop()
}
})
})
}
export default [...customRoutes()]
```
--------------------------------
### Add metadata example
Source: https://github.com/mquintal/react-router-mdx/blob/master/README.md
Example of how to use MDX file attributes to generate meta tags for SEO.
```ts
export function meta({ data: { attributes } }: Route.MetaArgs) {
return [
{ title: attributes.title },
{
property: "og:title",
content: attributes.title,
},
]
}
```
--------------------------------
### MDXComponents Usage Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/types.md
Example of how to define and use the MDXComponents type.
```typescript
const components: MDXComponents = {
h1: ({ children }) => (
{children}
),
a: ({ href, children }) => (
{children}
),
code: ({ children }) => (
{children}
),
YouTube: ({ id }: { id: string }) => (
)
}
```
--------------------------------
### Math Support
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Example of enabling math support using remarkMath and rehypeMathjax.
```typescript
import { loadMdx } from 'react-router-mdx/server'
import remarkMath from 'remark-math'
import rehypeMathjax from 'rehype-mathjax'
export async function loader({ request }) {
return await loadMdx(request, {
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeMathjax]
})
}
```
--------------------------------
### File Path to URL Path Transformation Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/architecture.md
Demonstrates how a file path is converted into a URL path.
```text
Input: /full/path/to/posts/blog/hello-world.mdx
Path: posts
Alias: (none)
Transformation:
1. Split by path: ['/full/path/to/', 'blog/hello-world.mdx']
2. Extract remainder: blog/hello-world.mdx
3. Remove .mdx: blog/hello-world
4. Convert to URL: /blog/hello-world or /posts/blog/hello-world
```
--------------------------------
### Options Configuration
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Examples of configuring paths and aliases for MDX files.
```typescript
import { init } from 'react-router-mdx'
// Single path
init({ path: 'posts', alias: 'blog' })
// Multiple paths with aliases
init({
paths: ['posts', 'articles'],
aliases: ['blog', 'docs']
})
```
--------------------------------
### loadMdx with CompileOptions Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/types.md
Example of using loadMdx with remark and rehype plugins.
```typescript
import { loadMdx } from 'react-router-mdx/server'
import remarkGfm from 'remark-gfm'
import rehypeHighlight from 'rehype-highlight'
export async function loader({ request }) {
return await loadMdx(request, {
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypeHighlight]
})
}
```
--------------------------------
### Example - Multiple collections
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/client.md
Demonstrates loading and using multiple collections of MDX files.
```typescript
import { loadAllMdx } from 'react-router-mdx/server'
export async function loader() {
const [posts, articles] = await Promise.all([
loadAllMdx(['posts']),
loadAllMdx(['articles'])
])
return { posts, articles }
}
export default function Collections() {
const { posts, articles } = useLoaderData() // Assuming useLoaderData is available
return (
<>
Posts
Articles
>
)
}
```
--------------------------------
### useMdxAttributes - Attribute Types Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/client.md
Example YAML front matter demonstrating different data types that can be parsed.
```yaml
---
title: My Post # string
date: 2024-01-01 # string (ISO format)
featured: true # boolean (YAML parses as boolean)
tags: # array
- javascript
- react
metadata: # object
views: 1000
likes: 42
---
```
--------------------------------
### Error: "Cannot find module or corresponding type declarations"
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Solution for the error 'Cannot find module or corresponding type declarations' by installing and importing the necessary plugin.
```bash
npm install remark-gfm
```
```typescript
import remarkGfm from 'remark-gfm'
await loadMdx(request, {
remarkPlugins: [remarkGfm]
})
```
--------------------------------
### Error Recovery Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Example of using a try-catch block in a loader to handle errors and return a Response.
```typescript
export async function loader({ request }) {
try {
return await loadMdx(request)
} catch (error) {
throw new Response('Post not found', { status: 404 })
}
}
```
--------------------------------
### Enable GitHub Flavored Markdown
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Example of enabling GitHub Flavored Markdown by including the remarkGfm plugin.
```typescript
import { loadMdx } from 'react-router-mdx/server'
import remarkGfm from 'remark-gfm'
export async function loader({ request }) {
return await loadMdx(request, {
remarkPlugins: [remarkGfm]
})
}
```
--------------------------------
### Example 3: Debugging Path Resolution
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/utilities.md
Demonstrates transforming file paths to URL paths and vice versa for debugging.
```typescript
import { getFilePathBasedOnUrl, transformFilePathToUrlPath } from 'react-router-mdx/server/utils'
// Test path transformation
const testFilePath = '/home/user/project/posts/hello.mdx'
const testPath = 'posts'
const testAlias = 'blog'
const urlPath = transformFilePathToUrlPath(testFilePath, testPath, testAlias)
console.log('File to URL:', testFilePath, '->', urlPath)
// Output: File to URL: /home/user/project/posts/hello.mdx -> blog/hello
// Reverse transformation
const reconstructedPath = getFilePathBasedOnUrl(
`https://example.com/${urlPath}`,
[testPath],
[testAlias]
)
console.log('URL to File:', urlPath, '->', reconstructedPath)
// Output: URL to File: blog/hello -> /home/user/project/posts/hello.mdx
```
--------------------------------
### Frontmatter Extraction Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/architecture.md
Shows how frontmatter is extracted from an MDX file using gray-matter.
```yaml
---
title: Hello World
date: 2024-01-01
tags:
- javascript
- react
---
# Hello World
Content here...
```
```json
{
"data": {
"title": "Hello World",
"date": "2024-01-01",
"tags": ["javascript", "react"]
},
"content": "# Hello World\nContent here..."
}
```
--------------------------------
### routes() generated output example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/server.md
Example of the route objects generated by the routes function for specific MDX files.
```typescript
[
{ path: 'posts/hello-world', file: './routes/post.tsx', id: 'posts/hello-world' },
{ path: 'posts/my-post', file: './routes/post.tsx', id: 'posts/my-post' }
]
```
--------------------------------
### MDX File Location - Multiple Collections
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Example of organizing MDX files for multiple content collections.
```plaintext
content/
├── posts/
│ ├── post-1.mdx
│ └── post-2.mdx
└── articles/
├── article-1.mdx
└── article-2.mdx
```
--------------------------------
### Slug Collisions with Aliases
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Configuration example for handling slug collisions with aliases by specifying multiple paths.
```typescript
init({
paths: ['posts', 'articles'],
aliases: ['blog', 'docs']
})
```
--------------------------------
### TypeScript Support
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Example demonstrating TypeScript type imports for API usage.
```typescript
import type { Route } from './+types/post'
import type { LoadData } from 'react-router-mdx/client'
import type { Options, MDXComponents } from 'react-router-mdx/server'
export async function loader({ request }: Route.LoaderArgs): Promise {
return await loadMdx(request)
}
const components: MDXComponents = {
h1: (props) =>
}
const options: Options = { path: 'posts' }
```
--------------------------------
### Basic loadMdx Usage Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/server.md
Example of how to use loadMdx in a React Router loader function to fetch MDX content.
```typescript
import { loadMdx } from 'react-router-mdx/server'
import type { Route } from './+types/post'
export async function loader({ request }: Route.LoaderArgs) {
return await loadMdx(request)
}
export default function Route() {
const { __raw, attributes } = useLoaderData()
// Use __raw and attributes in component
}
```
--------------------------------
### Example - Filter and sort
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/client.md
Shows how to filter and sort the results from useMdxFiles.
```typescript
export default function Archive() {
const allPosts = useMdxFiles()
const sortedPosts = allPosts
.filter(post => post.published === true)
.sort((a, b) => new Date(b.date) - new Date(a.date))
return (
{sortedPosts.map(post => (
))}
)
}
```
--------------------------------
### Plugin Support
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Example of configuring remark and rehype plugins for MDX compilation.
```typescript
import { loadMdx } from 'react-router-mdx/server'
import remarkGfm from 'remark-gfm'
import remarkMath from 'remark-math'
import rehypeHighlight from 'rehype-highlight'
import rehypeSlug from 'rehype-slug'
await loadMdx(request, {
remarkPlugins: [remarkGfm, remarkMath],
rehypePlugins: [rehypeHighlight, rehypeSlug]
})
```
--------------------------------
### app/routes/docs.tsx
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Loader function to fetch all MDX content for guides, API, and FAQ sections, and the component to display them.
```typescript
import { Link } from 'react-router'
import { loadAllMdx } from 'react-router-mdx/server'
export async function loader() {
const [guides, api, faq] = await Promise.all([
loadAllMdx(['guides']),
loadAllMdx(['api']),
loadAllMdx(['faq'])
])
return { guides, api, faq }
}
export default function DocsIndex() {
const { guides, api, faq } = useLoaderData()
return (
Documentation
Getting Started
{guides.map(g => (
{g.title}
))}
API Reference
{api.map(a => (
{a.title}
))}
FAQ
{faq.map(f => (
{f.title}
))}
)
}
```
--------------------------------
### Client-Side Rendering
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Example of using client-side hooks to get loader data and render the MDX component.
```typescript
import { useMdxComponent, useMdxAttributes } from 'react-router-mdx/client'
export default function Post() {
const Component = useMdxComponent() // Get rendererable component
const attributes = useMdxAttributes() // Get metadata
return // Render
}
```
--------------------------------
### Error: "Path(s) {paths} do not exist in url"
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Example demonstrating the error 'Path(s) {paths} do not exist in url' and its solution.
```typescript
// Config: path: 'posts'
// URL: /articles/hello-world
// Error: Path(s) posts were not found on URL
```
```typescript
// If this URL doesn't exist, add path to init():
init({
paths: ['posts', 'articles'],
aliases: ['blog', 'news']
})
```
--------------------------------
### Example of loading MDX with remark-gfm plugin
Source: https://github.com/mquintal/react-router-mdx/blob/master/README.md
This code snippet shows how to configure the `loadMdx` method to include the `remark-gfm` plugin for extended Markdown features.
```typescript
import { loadMdx } from 'react-router-mdx/server'
import remarkGfm from 'remark-gfm'
import type { Route } from "./+types/post";
export async function loader({ request }: Route.LoaderArgs) {
return loadMdx(request, { remarkPlugins: [remarkGfm] })
}
```
--------------------------------
### Server-Side Loading
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Example of using `loadMdx` in a route loader to get raw MDX code and attributes.
```typescript
import { loadMdx } from 'react-router-mdx/server'
export async function loader({ request }) {
return await loadMdx(request)
// Returns: { __raw: "export default function...", attributes: {...} }
}
```
--------------------------------
### useMdxAttributes - Accessing frontmatter
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/client.md
Example demonstrating how to use useMdxAttributes to access frontmatter for meta tags.
```typescript
import { useMdxAttributes } from 'react-router-mdx/client'
export function meta({ data }) {
const attributes = useMdxAttributes()
return [
{ title: attributes.title },
{ name: 'description', content: attributes.description }
]
}
```
--------------------------------
### Static Pre-rendering Integration
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/architecture.md
Example of integrating React Router MDX with a static pre-rendering process, showing how to discover MDX files and include them in the prerender list.
```typescript
// react-router.config.ts
import { init } from 'react-router-mdx/server'
const mdx = init({ path: 'posts' })
export default {
ssr: true,
async prerender() {
// 1. Discover all MDX files
const paths = await mdx.paths()
// 2. Include in prerender list
return ["/", ...paths]
// Returns: ["/", "/posts/hello-world", "/posts/my-post", ...]
}
}
```
--------------------------------
### useMdxComponent - Basic usage
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/client.md
Example demonstrating basic usage of useMdxComponent to render MDX content and access attributes.
```typescript
import { useMdxComponent, useMdxAttributes } from 'react-router-mdx/client'
import { loadMdx } from 'react-router-mdx/server'
export async function loader({ request }) {
return await loadMdx(request)
}
export default function Post() {
const Component = useMdxComponent()
const attributes = useMdxAttributes()
return (
{attributes.title}
)
}
```
--------------------------------
### Example 2: Custom Front Matter Processing
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/utilities.md
Extracts metadata from MDX files, including computed fields like word count and reading time.
```typescript
import { getFileContent, getAttributes } from 'react-router-mdx/server/mdx'
import { listMdxFilesSync } from 'react-router-mdx/server/utils'
async function extractPostMetadata() {
const files = listMdxFilesSync(['posts'])
const metadata = await Promise.all(
files[0].map(async (filePath) => {
const content = await getFileContent(filePath)
const attributes = getAttributes(content)
// Add computed fields
return {
...attributes,
filePath,
wordCount: content.split(/\s+/).length,
readingTime: Math.ceil(content.split(/\s+/).length / 200)
}
})
)
return metadata
}
```
--------------------------------
### Run and visit
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Run the development server and navigate to a post.
```bash
npm run dev
```
--------------------------------
### loadMdx Usage with Custom Plugins
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/server.md
Example demonstrating how to pass custom remark and rehype plugins to loadMdx.
```typescript
import { loadMdx } from 'react-router-mdx/server'
import remarkGfm from 'remark-gfm'
import type { Route } from './+types/post'
export async function loader({ request }: Route.LoaderArgs) {
return await loadMdx(request, {
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypeHighlight]
})
}
```
--------------------------------
### Simple Blog - react-router.config.ts
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Configuration for a simple blog using a single MDX content directory.
```typescript
// react-router.config.ts
import { init } from 'react-router-mdx/server'
const mdx = init({ path: 'posts' })
export default {
ssr: true,
async prerender() {
return [
"/",
"/blog",
...(await mdx.paths())
]
}
}
```
--------------------------------
### Project Structure
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
The file structure for a blog with listing and individual post pages.
```text
posts/
├── first-post.mdx
├── second-post.mdx
└── third-post.mdx
app/routes/
├── blog.tsx (index listing)
├── blog.$slug.tsx (individual posts)
└── +types/
├── blog.d.ts
└── blog.$slug.d.ts
react-router.config.ts
app/routes.tsx
```
--------------------------------
### Using test assertions in examples
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Avoid using test assertions in examples; use actual usage code instead.
```typescript
// ❌ WRONG - test code
const Component = useMdxComponent()
expect(Component).toBeDefined()
// ✅ CORRECT - usage code
const Component = useMdxComponent()
return
```
--------------------------------
### MDXComponents Structure Example
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/types.md
Example structure of the MDXComponents type, showing overrides for HTML elements and custom components.
```typescript
type MDXComponents = {
// HTML element overrides
h1?: React.ComponentType>
p?: React.ComponentType>
a?: React.ComponentType>
code?: React.ComponentType
pre?: React.ComponentType
// Custom MDX components
YouTube?: React.ComponentType<{ id: string }>
CodeBlock?: React.ComponentType<{ language: string; children: string }>
Alert?: React.ComponentType<{ type: string; children: React.ReactNode }>
[key: string]: React.ComponentType
}
```
--------------------------------
### init() options - Multiple paths
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/server.md
Structure for the options parameter when providing multiple paths for MDX files.
```typescript
{
paths: string[] // Array of directories containing MDX files
aliases?: string[] // Optional array of URL path prefixes (order matches paths)
}
```
--------------------------------
### Recommended Directory Structure
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
A recommended directory structure for a project using react-router-mdx.
```plaintext
project-root/
├── posts/ # MDX content directory
│ ├── hello-world.mdx
│ ├── my-first-post.mdx
│ └── nested/
│ └── nested-post.mdx
│
├── app/
│ ├── routes.tsx # Route definitions
│ └── routes/
│ └── post.tsx # Route Module for MDX files
│
├── react-router.config.ts # React Router config
├── package.json
└── tsconfig.json
```
--------------------------------
### init() options - Single path
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/server.md
Structure for the options parameter when providing a single path for MDX files.
```typescript
{
path: string // Directory containing MDX files
alias?: string // Optional URL path prefix (defaults to path value)
}
```
--------------------------------
### Blog Post Route Loader (Minimal Plugins)
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Loader function for blog post routes, configured to use minimal remark plugins for MDX loading.
```typescript
import { loadMdx } from 'react-router-mdx/server'
export async function loader({ request }) {
return await loadMdx(request, {
remarkPlugins: [] // Minimal plugins
})
}
```
--------------------------------
### Project Structure
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
This shows the directory structure for a multi-collection documentation site.
```tree
docs/
├── guides/
│ ├── getting-started.mdx
│ └── installation.mdx
├── api/
│ ├── overview.mdx
│ └── functions.mdx
└── faq/
├── common-questions.mdx
└── troubleshooting.mdx
app/routes/
├── docs.tsx (docs index)
├── docs.$path.tsx (any doc page)
└── +types/docs.$path.d.ts
react-router.config.ts
app/routes.tsx
```
--------------------------------
### app/routes/blog.tsx (Index)
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
The loader fetches all MDX posts and sorts them by date. The component renders a list of blog post cards.
```typescript
import { Link } from 'react-router'
import { useMdxFiles } from 'react-router-mdx/client'
import { loadAllMdx } from 'react-router-mdx/server'
export async function loader() {
const posts = await loadAllMdx()
return { posts: posts.sort((a, b) => new Date(b.date) - new Date(a.date)) }
}
export function meta() {
return [{ title: "Blog" }]
}
export default function Blog() {
const { posts } = useLoaderData()
return (
Blog Posts
{posts.map(post => (
{post.title}
{post.excerpt}
))}
)
}
```
--------------------------------
### Frontmatter Metadata Access
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/README.md
Example of accessing frontmatter metadata extracted from an MDX file.
```typescript
const { title, date, tags } = useMdxAttributes()
```
--------------------------------
### Pattern 2: Blog Index
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/client.md
A pattern for creating a blog index page using useMdxFiles.
```typescript
import { useMdxFiles } from 'react-router-mdx/client'
import { loadAllMdx } from 'react-router-mdx/server'
import { Link } from 'react-router' // Assuming react-router Link
export async function loader() {
return await loadAllMdx()
}
export default function Blog() {
const posts = useMdxFiles().sort((a, b) =>
new Date(b.date) - new Date(a.date)
)
return (
Blog
{posts.map(post => (
{post.title}
{post.excerpt}
))}
)
}
```
--------------------------------
### app/routes/blog.$slug.tsx (Post Page)
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Loads a specific MDX post with remark and rehype plugins for GFM and syntax highlighting. Renders the post content with its attributes.
```typescript
import { useMdxComponent, useMdxAttributes } from 'react-router-mdx/client'
import { loadMdx } from 'react-router-mdx/server'
import remarkGfm from 'remark-gfm'
import rehypeHighlight from 'rehype-highlight'
import type { Route } from './+types/blog.$slug'
export async function loader({ request }: Route.LoaderArgs) {
return await loadMdx(request, {
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypeHighlight]
})
}
export function meta({ data: { attributes } }: Route.MetaArgs) {
return [
{ title: attributes.title },
{ name: 'description', content: attributes.excerpt }
]
}
export default function PostPage() {
const Component = useMdxComponent()
const { title, date, author } = useMdxAttributes()
return (
{title}
{author}
)
}
```
--------------------------------
### Multiple Paths Configuration
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Configuration object for initializing react-router-mdx with multiple paths for MDX files and optional aliases.
```typescript
init({
paths: string[],
aliases?: string[]
})
```
--------------------------------
### app/routes/posts.tsx with custom components
Source: https://github.com/mquintal/react-router-mdx/blob/master/README.md
Example of a route module that registers custom components for use within MDX files.
```ts
const components = {
YouTube: ({ id }: { id: string }) => {
return (
)
}
}
export default function Route() {
const Component = useMdxComponent(components)
const attributes = useMdxAttributes()
return (
{attributes.title}
)
}
```
--------------------------------
### Dynamic MDX Plugin Configuration - App Routes
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Defines the application's routes, specifying different MDX loading configurations (plugins) for different route segments like blog posts, documentation, and tutorials.
```typescript
import { route } from "@react-router/dev/routes"
import { routes } from 'react-router-mdx/server'
export default [
// Blog posts use basic plugins
route("/blog/:slug", "routes/blog.$slug.tsx"),
// Documentation uses more plugins
route("/docs/:path", "routes/docs.$path.tsx"),
// Tutorials use code highlighting
route("/tutorials/:slug", "routes/tutorial.$slug.tsx"),
...routes("routes/fallback.tsx")
]
```
--------------------------------
### Lazy load plugins
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Only import plugins when needed to improve performance.
```typescript
export async function loader({ request }) {
let options = {}
// Only load if needed
if (request.url.includes('/tutorials/')) {
const rehypeHighlight = await import('rehype-highlight')
options.rehypePlugins = [rehypeHighlight.default]
}
return await loadMdx(request, options)
}
```
--------------------------------
### Single Path Configuration
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Configuration object for initializing react-router-mdx with a single path for MDX files.
```typescript
init({
path: string,
alias?: string
})
```
--------------------------------
### TypeScript Usage in Route Loader
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/types.md
Example of using TypeScript types for a route loader function with loadMdx.
```typescript
import type { Route } from './+types/post'
import { loadMdx } from 'react-router-mdx/server'
import type { LoadData } from 'react-router-mdx/client'
export async function loader({ request }: Route.LoaderArgs): Promise {
return await loadMdx(request)
}
```
--------------------------------
### Documentation Site with Multiple Collections - app/routes.tsx
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Route definitions for a documentation site with multiple MDX collections.
```typescript
// app/routes.tsx
import { route } from "@react-router/dev/routes"
import { routes } from 'react-router-mdx/server'
export default [
route("/", "routes/home.tsx"),
route("/docs/:path", "routes/doc.tsx"),
...routes("./routes/doc.tsx")
]
```
--------------------------------
### useMdxAttributes - Rendering attributes
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/client.md
Example showing how to use useMdxAttributes to render frontmatter attributes within a component.
```typescript
export default function Post() {
const { title, date, author, tags } = useMdxAttributes()
return (
{title}
By {author}
{tags?.map(tag =>
{tag}
)}
)
}
```
--------------------------------
### Usage Integration Step 1: Initialize
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/server.md
Code snippet for initializing react-router-mdx in react-router.config.ts.
```typescript
import { init } from 'react-router-mdx/server'
const mdx = init({ path: 'posts' })
```
--------------------------------
### Initialize React Router MDX
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Ensure init() is called before using routes.
```typescript
// ❌ WRONG - init() not called
export default [
...routes("./routes/post.tsx") // Error: not initialized
]
// ✅ CORRECT - init() called first
const mdx = init({ path: 'posts' })
export default [
...routes("./routes/post.tsx")
]
```
--------------------------------
### Define Custom Components with Type Safety
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/types.md
Example of defining custom MDX components with TypeScript type safety.
```typescript
import type { MDXComponents } from 'react-router-mdx/server'
const components: MDXComponents = {
h1: (props) => ,
YouTube: ({ id }: { id: string }) =>
}
```
--------------------------------
### TypeScript Usage in Route Component
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/types.md
Example of using TypeScript types for a route component to access loader data.
```typescript
import { useLoaderData } from 'react-router'
import { useMdxComponent, useMdxAttributes } from 'react-router-mdx/client'
import type { LoadData } from 'react-router-mdx/client'
export default function Post() {
const data = useLoaderData()
const Component = useMdxComponent()
const attributes = useMdxAttributes()
return
}
```
--------------------------------
### react-router.config.ts
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/patterns-and-recipes.md
Configuration file for initializing react-router-mdx with multiple collection paths and aliases.
```typescript
import { init } from 'react-router-mdx/server'
const mdx = init({
paths: ['docs/guides', 'docs/api', 'docs/faq'],
aliases: ['guides', 'api', 'faq']
})
export default {
ssr: true,
async prerender() {
return ["/", "/docs", ...(await mdx.paths())]
}
}
```
--------------------------------
### loadAllMdx Usage with Path Filtering
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/api-reference/server.md
Example showing how to filter MDX files using loadAllMdx with a specific path.
```typescript
import { loadAllMdx } from 'react-router-mdx/server'
export async function loader() {
// When init was called with paths: ['posts', 'articles']
const articlesOnly = await loadAllMdx(['articles'])
// Only returns files from the 'articles' folder
}
```
--------------------------------
### Documentation Site with Multiple Collections - react-router.config.ts
Source: https://github.com/mquintal/react-router-mdx/blob/master/_autodocs/configuration.md
Configuration for a documentation site with multiple MDX content collections.
```typescript
// react-router.config.ts
import { init } from 'react-router-mdx/server'
const mdx = init({
paths: ['docs/guides', 'docs/api', 'docs/faq'],
aliases: ['guides', 'api', 'faq']
})
export default {
ssr: true,
async prerender() {
return ["/", ...(await mdx.paths())]
}
}
```