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 _meta.js file is one of the most important conventions in a Nextra project. By placing a _meta.js file inside any content directory, you control the order pages appear in the sidebar, assign human-readable titles, add external links, define section separators, and create dropdown menus — all without touching individual page files.

How It Works

Nextra collects _meta.js files from two locations:
  • app/ directory — alongside page.md and page.mdx files
  • content/ directory — alongside .md and .mdx files
The information from every _meta.js file is merged into a site-wide pageMap that your Nextra theme uses to render the sidebar and navbar.
If a route is not listed in _meta.js, Nextra still includes it in the sidebar, appended at the end in alphabetical order (with index always first if unlisted).

Basic Usage

A _meta.js file exports a default object. The keys are page slugs (matching file names without extensions); the values are either a string title or a configuration object:
_meta.js
export default {
  index: 'Home',
  'getting-started': 'Getting Started',
  contact: {
    title: 'Contact Us',
    href: 'https://example.com/contact'
  }
}
For TypeScript projects, import the MetaRecord type for full type safety:
_meta.ts
import type { MetaRecord } from 'nextra'

const meta: MetaRecord = {
  index: 'Home',
  'getting-started': 'Getting Started'
}

export default meta
The .js, .jsx, and .tsx file extensions are all supported for _meta files.

Title Types

Titles can be a plain string or a JSX element, allowing you to embed icons or styled text directly in the sidebar:
_meta.jsx
import { GitHubIcon } from 'nextra/icons'

export default {
  index: 'My Homepage',
  // JSX titles let you add icons, colors, or custom components
  contact: (
    <Italic className="my-class">
      <GitHubIcon height="20" />
      Contact Us
    </Italic>
  ),
  about: {
    title: 'About Us'
    // extra config options go here alongside `title`
  }
}

function Italic({ children, ...props }) {
  return <i {...props}>{children}</i>
}

Page Item Options

When a value is an object (rather than a plain string), the following fields are available:
type PageItemSchema = {
  type?: 'page' | 'doc'     // default: 'doc'
  display?: 'normal' | 'hidden' | 'children'  // default: 'normal'
  title?: string | ReactElement
  theme?: PageThemeSchema
}

type: 'page' — Promote to Navbar

By setting type: 'page', a top-level entry is displayed in the navigation bar instead of the sidebar. This enables “sub-docs” — multiple distinct documentation sections that each appear as a top-level nav item:
_meta.js
export default {
  index: {
    title: 'Home',
    type: 'page'
  },
  frameworks: {
    title: 'Frameworks',
    type: 'page'
  },
  fruits: {
    title: 'Fruits',
    type: 'page'
  },
  about: {
    title: 'About',
    type: 'page'
  }
}
Use the '*' wildcard key as a fallback to apply type: 'page' to every item without repeating the config:
_meta.js
export default {
  '*': { type: 'page' },
  index: 'Home',
  frameworks: 'Frameworks',
  fruits: 'Fruits',
  about: 'About'
}

display: 'hidden' — Hide from Sidebar

The page remains accessible via its URL but is not shown in the sidebar:
_meta.js
export default {
  contact: {
    display: 'hidden'
  }
}

display: 'children' — Show Children, Hide Folder

When applied to a folder, display: 'children' hides the folder itself from the sidebar while still rendering all its child pages. This is useful for grouping content logically without creating a visible parent node:
_meta.js
export default {
  internal: {
    display: 'children'
  }
}

theme — Per-Page Theme Overrides

The theme option lets you toggle individual UI components on or off for a specific page (or an entire folder):
_meta.js
export default {
  about: {
    theme: {
      sidebar: false,
      toc: false,
      footer: true
    }
  }
}
Theme settings on a folder are inherited by all child pages. Use this intentionally when you want a consistent layout for an entire section.
The full set of theme fields:
FieldTypeDefaultDescription
breadcrumbbooleantrueShow/hide breadcrumb navigation
collapsedbooleanfalseCollapse the sidebar item by default
copyPagebooleantrueShow/hide the “Copy page” button
footerbooleantrueShow/hide the page footer
layout'default' | 'full''default'Page layout style ('full' uses the full container width)
navbarbooleantrueShow/hide the top navigation bar
paginationbooleantrueShow/hide prev/next pagination controls
sidebarbooleantrueShow/hide the sidebar
timestampbooleantrueShow/hide the last-updated timestamp
tocbooleantrueShow/hide the table of contents
typesetting'default' | 'article''default'Text typesetting style ('article' for editorial pages)

Layouts

The layout: 'full' setting stretches a page’s content to fill the entire container width — useful for landing pages or dashboards:
_meta.js
export default {
  dashboard: {
    theme: {
      layout: 'full'
    }
  }
}

Typesetting

The 'article' typesetting applies editorial font features and refined heading styles, ideal for long-form content:
_meta.js
export default {
  blog: {
    theme: {
      typesetting: 'article'
    }
  }
}
Add an href field to any item to turn it into an external (or internal) link in the sidebar:
_meta.js
export default {
  github_link: {
    title: 'Nextra on GitHub',
    href: 'https://github.com/shuding/nextra'
  }
}

Separators

Use a key whose value has type: 'separator' to insert a visual divider in the sidebar. The title field is optional and renders as a section label:
_meta.js
export default {
  '---': {
    type: 'separator',
    title: 'Resources' // omit for a plain horizontal rule
  },
  changelog: 'Changelog',
  roadmap: 'Roadmap'
}
Create a dropdown menu in the navbar by setting type: 'menu' with an items record:
_meta.js
export default {
  company: {
    title: 'Company',
    type: 'menu',
    items: {
      about: {
        title: 'About',
        href: '/about'
      },
      contact: {
        title: 'Contact Us',
        href: 'mailto:hi@example.com'
      }
    }
  }
}

Folders with Index Pages

To make a folder clickable (expand it and show its index.mdx page), add asIndexPage: true to the folder’s index file front matter:
content/fruits/index.mdx
---
title: All Fruits
sidebarTitle: 🍒 Fruits
asIndexPage: true
---

Nested _meta.js Files

Each directory can have its own _meta.js covering only its immediate children. Top-level pages and folders are configured by the root _meta.js; subdirectory pages are configured by the _meta.js inside that subdirectory:
export default {
  index: 'My Homepage',
  contact: 'Contact Us',
  fruits: 'Delicious Fruits',
  about: 'About Us'
}

Global _meta.global.js File

Instead of multiple per-directory _meta.js files, you can define your entire navigation tree in a single _meta.global.js file at the project root. Folder entries must include an items field:
_meta.global.js
export default {
  fruits: {
    type: 'page',
    title: '✨ Fruits',
    items: {
      apple: '🍎 Apple',
      banana: '🍌 Banana'
    }
  }
}
You cannot use both _meta.global.js and per-directory _meta.js files in the same project. Choose one approach.

Good to Know

To enforce alphabetical key order in your _meta files, add an ESLint comment at the top of the file:
_meta.js
/* eslint sort-keys: error */
export default {
  about: 'About',
  contact: 'Contact',
  index: 'Home'
}
JavaScript objects sort numeric keys before string keys. A key like 1992_10_21 is silently coerced to 19921021 and moved to the front of the object — breaking your intended order. Always quote keys that look like numbers:
_meta.js
export default {
  // ❌ Bad — numeric-looking keys are reordered by JS
  1992_10_21: 'Founding Day',
  // ✅ Good — string keys preserve insertion order
  'founding-day': 'Founding Day'
}

Build docs developers (and LLMs) love