The Nextra Blog Theme (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.
nextra-theme-blog) is a minimal, typography-focused layout for publishing markdown blog posts with Next.js App Router. It provides a post listing page with dates and reading times, a tags system for categorisation, RSS feed generation, a dark mode toggle, and a flexible navbar — all with very little configuration required.
What’s Included
Post Listing
Display all posts sorted by date, with titles, descriptions, and publication timestamps using the
<PostCard> component.Tags System
Filter posts by tag. Generate static tag pages with
generateStaticParams using the getTags helper.RSS Feed
Generate a standards-compliant
rss.xml route from your page map data using a Next.js Route Handler.Theme Switcher
Built-in
<ThemeSwitch> component for light/dark/system theme selection via next-themes.Navigation Bar
<Navbar> component that auto-generates top-level nav links from your page map, with slots for search and other children.Reading Time
Enable
readingTime: true in your Nextra config to automatically attach reading time metadata to every post.Installation
Enable the
readingTime option if you want per-post reading time automatically computed from your MDX content:import nextra from 'nextra'
const withNextra = nextra({
defaultShowCopyCode: true,
readingTime: true
})
export default withNextra({
reactStrictMode: true
})
Import
Layout, Navbar, Footer, and ThemeSwitch from nextra-theme-blog and compose them in your app/layout.jsx:import { Footer, Layout, Navbar, ThemeSwitch } from 'nextra-theme-blog'
import { Banner, Head, Search } from 'nextra/components'
import { getPageMap } from 'nextra/page-map'
import 'nextra-theme-blog/style.css'
export const metadata = {
title: 'My Blog'
}
export default async function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<Head />
<body>
<Layout>
<Navbar pageMap={await getPageMap()}>
<Search />
<ThemeSwitch />
</Navbar>
{children}
<Footer>
CC BY-NC 4.0 {new Date().getFullYear()} © Your Name.
<a href="/rss.xml" style={{ float: 'right' }}>
RSS
</a>
</Footer>
</Layout>
</body>
</html>
)
}
Post Frontmatter
Each blog post is an MDX file inside yourapp/posts/ directory. Declare metadata in the frontmatter block at the top of the file. All fields are optional, but title and date are recommended for the post listing to display correctly.
BlogMetadata Type
TheBlogMetadata type describes the shape of the frontmatter object available on every processed post. All fields are optional.
The
readingTime field is populated automatically by Nextra when you set readingTime: true in next.config.js. It uses remark-reading-time under the hood and adds a ReadingTime object containing text (e.g. "3 min read") and minutes to the frontmatter of every MDX file.Layout Component
The<Layout> component wraps your application in a ThemeProvider from next-themes and applies the blog’s base typography styles via a <article> container.
Props
The page content — passed automatically by Next.js as
{children} in the root layout.A banner element displayed above the navbar. Use the
<Banner> component from nextra/components.Configuration for
next-themes ThemeProvider. Accepts all ThemeProvider props except children. Useful for overriding attribute, defaultTheme, or storageKey.Navbar Component
The<Navbar> component reads your page map to automatically render top-level navigation links, then slots in any children (such as a search box or theme switch) on the right side.
Props
The result of
getPageMap() from nextra/page-map. Top-level items in the page map become nav links.Additional elements rendered after the nav links — typically
<Search /> and <ThemeSwitch />.Footer Component
The<Footer> component renders a small footer below the article content. Pass children for copyright text, license info, or an RSS link.
Getting Posts and Tags
The blog theme does not provide a built-ingetPosts helper — you create a small utility that calls getPageMap() and processes the results. This runs at build time as a Server Component or inside Route Handlers.
posts/get-posts.js
Create a shared helper module that both the posts listing page and the tag pages can import:Posts Listing Page
The posts page fetches all posts and their tags, then renders them using<PostCard>:
PostCard Component
The<PostCard> component renders a single post preview with title, description, date, and a “Read More” link.
The post object from
getPosts(). Must have a route string and a frontMatter object following the BlogMetadata shape.The text of the “read more” link appended to the description. Set to an empty string
"" or leave it undefined to hide the link.Tags Page
UsegenerateStaticParams to pre-render a page for each unique tag at build time:
RSS Feed
Generate a standard RSS 2.0 feed by creating a Next.js Route Handler atapp/rss.xml/route.js. This file runs server-side and returns a valid XML response:
The Route Handler approach means the RSS feed is generated at request time (or cached at build time with
export const dynamic = 'force-static'). Link to it from your footer with <a href="/rss.xml">RSS</a> and add a <link> element in your <Head> for feed autodiscovery.Comments Integration
The blog theme includes a<Comments> component backed by Cusdis, a lightweight, privacy-friendly comment system. Wrap individual post layouts with it to enable per-post comments:
ThemeSwitch Component
The standalone<ThemeSwitch> component renders a dark/light/system mode toggle. It is typically placed inside the <Navbar> but can be used anywhere in the tree.
All Named Exports
The following are all named exports available fromnextra-theme-blog:
| Export | Type | Description |
|---|---|---|
Layout | Component | Root layout — wraps content in ThemeProvider and article container |
Navbar | Component | Top navigation bar with auto-generated links from pageMap |
Footer | Component | Page footer with optional children |
ThemeSwitch | Component | Dark/light/system mode toggle |
PostCard | Component | Individual post preview card (title, description, date) |
Comments | Component | Cusdis-powered comment section |
useMDXComponents | Hook | MDX component map — re-export from mdx-components.js |
useTheme | Hook | Re-exported from next-themes — read the active theme |
Complete Example Structure
A typical blog project usingnextra-theme-blog has this file layout: