_meta.js
File
In Nextra, the site and individual page structure can be configured via the
co-located _meta
files. Those configurations affect the overall layout of your
Nextra theme, especially the navigation bar and the sidebar:
Organizing files
Nextra allows you to organize files in the following ways:
-
In Next.js’
app
directory:
Nextra gathers allpage
files, includingpage.md
andpage.mdx
files as well as_meta
files. -
In Nextra’s
content
directory:
Nextra collects all.md
and.mdx
files, along with_meta
files.
Below the same file-based routing structure is represented for content
and
app
-only directories:
- Using
- layout.jsx
- _meta.js
- index.mdx
- legal.md
- _meta.js
- contact.md
- index.mdx
content
directory- Using
- _meta.js
- page.mdx
- _meta.js
- layout.jsx
- page.mdx
page.mdx
filesYou can combine both organizational ways for your project:
- the
content
directory with.mdx
files - the
app
directory withpage
files
pageMap
structure
Afterward, Nextra generates a pageMap
array containing information about your
entire site’s routes and directories structure. Features such as the navigation
bar and sidebar can be generated based on the pageMap
information.
The generated pageMap
will be:
[
// content/_meta.js
{ "data": {} },
// content/index.mdx
{ "name": "index", "route": "/", "frontMatter": {} },
// content/contact.md
{ "name": "contact", "route": "/contact", "frontMatter": {} },
{
// content/about
"name": "about",
"route": "/about",
"children": [
// content/about/_meta.js
{ "data": {} },
// content/about/index.mdx
{ "name": "index", "route": "/about", "frontMatter": {} },
// content/about/legal.md
{ "name": "legal", "route": "/about/legal", "frontMatter": {} }
],
"title": "About"
}
]
And the global pageMap
will be imported to each page by Nextra. Then,
configured theme will render the actual UI with that pageMap
.
API
The title and order of a page shown in the sidebar/navbar can be configured in
the _meta
file as key-value pairs.
import type { MetaRecord } from 'nextra'
/**
* type MetaRecordValue =
* | TitleSchema
* | PageItemSchema
* | SeparatorSchema
* | MenuSchema
*
* type MetaRecord = Record<string, MetaRecordValue>
**/
const meta: MetaRecord = {
// ...
}
export default meta
title
type
When specifying a title
in _meta
file, you can define it as either a simple
string or a JSX element.
type TitleSchema = string | ReactElement
For the below file structure:
- Using
- layout.jsx
- _meta.js
- about.mdx
- contact.mdx
- index.mdx
content
directory- Using
- _meta.js
- layout.jsx
- page.mdx
page.mdx
filesThe following _meta
file defines pages titles:
import { GitHubIcon } from 'nextra/icons'
export default {
index: 'My Homepage',
// You can use JSX elements to change the look of titles in the sidebar, e.g. insert icons
contact: (
<Italic className="my-class">
<GitHubIcon height="20" />
Contact Us
</Italic>
),
about: {
// Alternatively, you can set title with `title` property
title: 'About Us'
// ... and provide extra configurations
}
}
// Custom component for italicized text
function Italic({ children, ...props }) {
return <i {...props}>{children}</i>
}
Pages
In _meta
file you can define how the pages are shown in the sidebar, e.g. for
the following file structure:
- Using
- layout.jsx
- _meta.js
- about.mdx
- contact.mdx
- index.mdx
content
directory- Using
- _meta.js
- layout.jsx
- page.mdx
page.mdx
filesexport default {
index: 'My Homepage',
contact: 'Contact Us',
about: 'About Us'
}
If any routes are not listed in the _meta
file, they will be appended to the
end of the sidebar and sorted alphabetically (except for index
key which
comes first if it’s not specified in _meta
file).
type PageItemSchema = {
type: 'page' | 'doc' // @default 'doc'
display: 'normal' | 'hidden' | 'children' // @default 'normal'
title?: TitleSchema
theme?: PageThemeSchema
}
type: 'page'
option
By defining a top-level page or folder as type: 'page'
, it will be shown
as a special page on the navigation bar, instead of the sidebar. With this
feature, you can have multiple “sub docs”, and special pages or links such as
“Contact Us” that are always visible.
For example, you can have 2 docs folders frameworks
and fruits
in your
project. In your top-level _meta
file, you can set everything as a page,
instead of a normal sidebar item:
- Using
- layout.jsx
- react.mdx
- svelte.mdx
- vue.mdx
- apple.mdx
- banana.mdx
- _meta.js
- about.mdx
- index.mdx
content
directory- Using
- _meta.js
- layout.jsx
- page.mdx
page.mdx
filesexport default {
index: {
title: 'Home',
type: 'page'
},
frameworks: {
title: 'Frameworks',
type: 'page'
},
fruits: {
title: 'Fruits',
type: 'page'
},
about: {
title: 'About',
type: 'page'
}
}
And it will look like this:
You can also hide links like Home
from the navbar with the
display: 'hidden'
option.
You can have external links in the navbar, similar to the links section:
export default {
contact: {
title: 'Contact Us',
type: 'page',
href: 'https://example.com/contact'
}
}
display: 'hidden'
option
By default, all MDX routes in the filesystem will be shown on the sidebar. But
you can hide a specific pages or folders by using the display: 'hidden'
configuration:
export default {
contact: {
display: 'hidden'
}
}
The page will still be accessible via the /contact
URL, but it will not be
shown in the sidebar.
theme
option
You can configure the theme for each page using the theme
option. For example,
you can disable or enable specific components for specific pages:
export default {
about: {
theme: {
sidebar: false
}
}
}
This option will be inherited by all child pages if set to a folder.
Option | Type | Default Value | Description |
---|---|---|---|
breadcrumb | boolean | true | Show or hide breadcrumb navigation. |
collapsed | boolean | false | Indicates whether the item in sidebar is collapsed by default. |
footer | boolean | true | Specifies whether to display the footer. |
layout | 'default' | 'full' | 'default' | Defines the layout style. |
navbar | boolean | true | Specifies whether to display the navbar. |
pagination | boolean | true | Determines if pagination controls are shown. |
sidebar | boolean | true | Specifies whether to display the sidebar. |
timestamp | boolean | true | Indicates if “last updated” timestamps are displayed. |
toc | boolean | true | Determines whether a table of contents is displayed. |
typesetting | 'default' | 'article' | 'default' | Configures the text typesetting style. |
Layouts
By default, each page has layout: 'default'
in their theme config, which
is the default behavior. You might want to render some page with the full
container width and height, but keep all the other styles. You can use the
'full'
layout to do that:
export default {
about: {
theme: {
layout: 'full'
}
}
}
Typesetting
The typesetting
option controls typesetting details like font features,
heading styles and components like <li>
and <code>
. There are
'default'
and 'article'
typesettings available in the docs theme.
The default one is suitable for most cases like documentation, but you can use
the 'article'
typesetting to make it look like an elegant article page:
Folders
Folders can be configured in the same way as pages.
For example, the following top-level _meta
file contains the meta information
for the top-level pages and folders.
The nested _meta
file contains the
meta information for pages in the same folder:
- Using
- layout.jsx
- _meta.js
- apple.mdx
- banana.mdx
- _meta.js
- about.mdx
- contact.mdx
- index.mdx
content
directory- Using
- _meta.js
- _meta.js
- layout.jsx
- page.mdx
page.mdx
filesexport default {
index: 'My Homepage',
contact: 'Contact Us',
fruits: 'Delicious Fruits',
about: 'About Us'
}
export default {
apple: 'Apple',
banana: 'Banana'
}
You can move directories around without having to change the _meta
file
since information for pages are grouped together in directories.
With /index
page
To create a folder with an index page, add asIndexPage: true
to its front
matter.
For example, to create a /fruits
route, setting asIndexPage: true
tells
Nextra that /fruits
is a folder with an index page. Clicking the folder in the
sidebar will expand it and display the MDX page.
- Using
- layout.jsx
- _meta.js
- apple.mdx
- banana.mdx
- index.mdx
- _meta.js
- about.mdx
- contact.mdx
- index.mdx
content
directory- Using
- _meta.js
- page.mdx
- _meta.js
- layout.jsx
- page.mdx
page.mdx
files---
title: All Fruits
sidebarTitle: 🍒 Fruits
asIndexPage: true
---
Links
type LinkSchema = {
href: string
title?: TitleSchema
}
You can add external links to the sidebar by adding an item with href
in
_meta
file:
export default {
github_link: {
title: 'Nextra',
href: 'https://github.com/shuding/nextra'
}
}
You can use this option to link to relative internal links too.
Separators
type SeparatorSchema = {
type: 'separator'
title?: TitleSchema
}
You can use a “placeholder” item with type: 'separator'
to create a
separator line between items in the sidebar:
export default {
'###': {
type: 'separator',
title: 'My Items' // Title is optional
}
}
Menus
You can also add menus to the navbar using type: 'menu'
and the items
option:
type MenuItemSchema =
| TitleSchema
| { title: TitleSchema }
| (LinkSchema & { type?: 'page' | 'doc' })
| SeparatorSchema
type MenuSchema = {
type: 'menu'
title?: TitleSchema
items: Record<string, MenuItemSchema>
}
export default {
company: {
title: 'Company',
type: 'menu',
items: {
about: {
title: 'About',
href: '/about'
},
contact: {
title: 'Contact Us',
href: 'mailto:hi@example.com'
}
}
}
}
Fallbacks
In the type: 'page'
option above, we have to define
the type: 'page'
option for every page. To make it easier, you can use
the '*'
key to define the fallback configuration for all items in this folder:
export default {
'*': {
type: 'page'
},
index: 'Home',
frameworks: 'Frameworks',
fruits: 'Fruits',
about: 'About'
}
They are equivalent where all items have type: 'page'
set.
_meta.global
file
You can also define all your pages in a single _meta
file, suffixed with
.global
. The API remains the same as for folder-specific _meta
files, with 1
exception: folder items must include an items
field.
For the following structure, you might use the following _meta
files:
- Using
- layout.jsx
- _meta.js
- apple.mdx
- banana.mdx
- _meta.js
- index.mdx
content
directory- Using
- _meta.js
- _meta.js
- layout.jsx
- page.mdx
page.mdx
filesexport default {
fruits: {
type: 'page',
title: '✨ Fruits'
}
}
export default {
apple: '🍎 Apple',
banana: '🍌 BaNaNa'
}
With single _meta.global
file it can be defined as below:
export default {
fruits: {
type: 'page',
title: '✨ Fruits',
items: {
apple: '🍎 Apple',
banana: '🍌 BaNaNa'
}
}
}
You can’t use both _meta.global
and _meta
files in your project.
Good to know
Sorting pages
You can use ESLint’s built-in sort-keys
rule, append
/* eslint sort-keys: error */
comment at the top of your _meta
file, and you
will receive ESLint’s errors about incorrect order.
Type of _meta
keys
The type of your _meta
keys should always be a string and not a number
because
numbers are always ordered first
in JavaScript objects.
For example, consider the following:
export default {
foo: '',
1992_10_21: '',
1: ''
}
will be converted to:
export default {
'1': '',
'19921021': '',
foo: ''
}
The .js
, .jsx
, or .tsx
file extensions can be used for _meta
file.