Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/shuding/nextra/llms.txt

Use this file to discover all available pages before exploring further.

The page.mdx (and page.md) file is Nextra’s integration point with the Next.js App Router. When you place an MDX file named page.mdx inside a folder under app/, Next.js treats it just like any other page file — but Nextra’s webpack loader processes the MDX content, adds syntax highlighting, parses front matter, and makes the page part of the site-wide pageMap.

What is a page File?

A page file is a Next.js App Router convention that defines the UI rendered for a specific route. By default Next.js supports .js, .jsx, and .tsx extensions. Nextra extends this with .md and .mdx so you can author content directly as Markdown.

Directory Structure

Place page.mdx files anywhere inside your app/ directory, just as you would a regular page.tsx:
app/
├── layout.jsx
├── page.jsx                         → /
└── docs/
    ├── page.mdx                     → /docs
    └── getting-started/
        └── page.mdx                 → /docs/getting-started
The .md and .mdx extensions are interchangeable. Use whichever fits your workflow — Nextra processes both identically.

Comparing content/ vs app/ Approach

Both approaches produce the same rendered output, but they have different trade-offs:
Files live in content/, not in app/. A single catch-all route ([[...mdxPath]]/page.jsx) handles all content rendering.
content/
└── docs/
    ├── intro.mdx           ← file you edit
    └── getting-started.mdx

app/
└── [[...mdxPath]]/
    └── page.jsx            ← single gateway file
Best for: Large documentation sites, easy migration from the pages/ router, content that changes frequently.
You can combine both approaches in the same project. Nextra collects page.mdx files from app/ and .mdx files from content/ together into a unified pageMap.

How Nextra Processes page.mdx

Nextra registers a webpack loader that intercepts .md and .mdx files loaded as Next.js pages. The loader:
  1. Parses YAML front matter from the file.
  2. Compiles MDX to JavaScript (using @mdx-js/mdx).
  3. Applies syntax highlighting via rehype-pretty-code.
  4. Injects a metadata export that Next.js uses for <head> tags (title, description, Open Graph, etc.).
  5. Adds the page to the pageMap that powers the sidebar and navbar.

Front Matter Fields

Nextra reads YAML front matter at the top of every page.mdx file. The following fields have special meaning:
FieldTypeDescription
titlestringPage title — used in the <title> tag and sidebar
descriptionstringPage description for the <meta name="description"> tag
sidebarTitlestringShorter title shown in the sidebar when it differs from title
iconstringIcon name displayed next to the page in the sidebar
asIndexPagebooleanMarks a folder’s index.mdx as a clickable folder index
app/docs/getting-started/page.mdx
---
title: Getting Started with Nextra
description: Install Nextra and create your first documentation site.
sidebarTitle: Getting Started
---

# Getting Started

...

The $NextraMetadata Type

Every compiled Nextra page exports a metadata object that extends the Next.js Metadata type. Its TypeScript shape is:
type $NextraMetadata = Omit<Metadata, 'title'> & {
  /** The plain-text page title resolved from front matter or the first heading. */
  title: string
  /** The file path of the source MDX file, relative to the project root. */
  filePath: string
  /** Last-modified timestamp (Unix ms). Present when `timestamp` is enabled in the page theme options. */
  timestamp?: number
  /** Estimated reading time. Present when `readingTime: true` is set in nextra config. */
  readingTime?: {
    text: string     // e.g. "3 min read"
    minutes: number  // e.g. 3.2
    time: number     // milliseconds
    words: number    // word count
  }
}
You can access the metadata export in a layout or theme to display reading time, a last-updated badge, or breadcrumbs:
app/docs/layout.tsx
import type { $NextraMetadata } from 'nextra'

export default function DocsLayout({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>
}
Enable estimated reading time by setting readingTime: true in your nextra() configuration inside next.config.mjs. The timestamp field is populated when your Nextra theme has timestamp rendering enabled.

Enabling Reading Time

next.config.mjs
import nextra from 'nextra'

const withNextra = nextra({
  readingTime: true
})

export default withNextra({})
Once enabled, front matter in every .md and .mdx file will include a readingTime key computed by the reading-time package.

Build docs developers (and LLMs) love