Skip to Content
BlogsNextra 4.0: Docs setup guide

Building a Documentation Site with Next.js and Nextra 4.0

This guide walks you through creating a modern documentation website using Next.js with the App Router and Nextra 4.0’s Docs theme. Following these steps carefully should result in a fully functional site. The process involves setting up a development environment, configuring Next.js and Nextra, structuring content, enabling search, and deploying to platforms like Vercel or Cloudflare Pages.

Key Points:

  • Next.js 13+ requires Node.js >18.17.0; Nextra 4.0 utilizes the App Router.
  • The setup includes TypeScript, ESLint, and Tailwind CSS for robust development.
  • Deployment on Cloudflare Pages requires the nodejs_compat flag for Node.js APIs.
  • Common issues like build failures or sidebar errors can often be resolved with specific configuration checks.
  • Extensive customization options allow tailoring the site’s appearance and functionality.

Prerequisites

A working installation of Node.js, npm, and Git is required. This guide uses PowerShell commands, adaptable for other terminals. A recent Node.js LTS version (e.g., 18.18.0 or 20.0.0+) is recommended for Next.js compatibility.

Project Setup

The process uses create-next-app to bootstrap a Next.js project, subsequently integrating Nextra and the Docs theme. Configurations for TypeScript and Tailwind CSS are included to enhance the development workflow.

Deployment

Vercel offers seamless Next.js integration. Cloudflare Pages provides excellent performance but necessitates the nodejs_compat flag for full Node.js API support. Both platforms are well-suited for static site deployment, ideal for documentation.

Customization

The theme and functionality can be extensively customized, including internationalization (i18n) and integration of remote MDX content.


Comprehensive Guide: Next.js & Nextra 4.0 Documentation Site

This guide provides a validated, step-by-step process for creating a documentation or content-focused website using Next.js (specifically the App Router) and Nextra 4.0 with its Docs theme (nextra-theme-docs). It includes detailed technical explanations, dependency checks, installation commands, and justifications for each step. Deployment on Vercel and Cloudflare Pages, common troubleshooting, customization, and FAQs are also covered.

1. Core Technologies

The site leverages the following key technologies:

  • Next.js: A React framework for building server-rendered or statically generated applications, featuring the App Router for modern routing and React Server Components.
  • Nextra: A specialized framework built upon Next.js, optimized for creating content-heavy websites such as documentation and blogs.
  • MDX: An enhanced version of Markdown that allows embedding JSX, enabling the use of dynamic React components directly within content files.
  • nextra-theme-docs: A feature-rich theme for Nextra, providing pre-built layouts, sidebar navigation, a navigation bar, search functionality, and dark mode support.
  • Pagefind: A static search library integrated with Nextra 4.0, used for indexing site content and enabling client-side search capabilities.

Justification: This technology stack is selected for its robust ecosystem, developer-friendliness, and suitability for documentation websites. Next.js provides scalability and performance, Nextra simplifies content management and site structure, and Pagefind offers efficient, static search functionality.

2. Prerequisites: Setting Up Your Development Environment

Before initiating the project, ensure your development environment meets the necessary requirements. Commands are provided for PowerShell but can be adapted for other terminal environments (e.g., Bash on Linux/macOS).

2.1 Node.js and npm

Purpose: Node.js serves as the runtime for the Next.js application, while npm (Node Package Manager) is used for managing project dependencies.

Dependency Check:

  • Command: Execute in PowerShell to verify installed versions:
    node -v npm -v

Expected Output: Node.js version 18.17.0 or higher (as required by Next.js 13 and later), npm version 9.0.0 or higher is typical with newer Node.js versions.

Installation (if Node.js/npm are missing or outdated):

  • Download: Obtain the latest Long-Term Support (LTS) version from the Node.js Official Website.
  • Install: Execute the downloaded installer (e.g., node-v20.x.x-x64.msi).
    # Example: Start-Process -FilePath "C:\path\to\node-v20.x.x-x64.msi" -ArgumentList "/quiet" -Wait
  • Verify Installation: Close and reopen PowerShell, then run:
    node -v npm -v

npm Registry Check:

  • Command: npm config get registry
  • Expected Output: https://registry.npmjs.org/
  • Correction (if needed): npm config set registry https://registry.npmjs.org/

Justification: Compatibility with Next.js 13+ necessitates Node.js 18.17.0 or newer, as per the Next.js documentation. The verification script aids in confirming this. npm is the standard package manager for Node.js projects.

2.2 Git

Purpose: Git facilitates version control, collaboration, and deployment to various hosting platforms like Vercel and Cloudflare Pages.

Dependency Check:

  • Command: git --version
  • Expected Output: A recent version, e.g., git version 2.x.x.

Installation (if missing):

  • Download: Get the appropriate installer from the Git Official Website.
  • Install: Run the installer, following the on-screen prompts.
  • Verify Installation: Close and reopen PowerShell, then execute git --version.

Justification: Git is the industry standard for source code management and is integral to modern deployment workflows.

3. Project Setup with Create Next App

Bootstrap your Next.js project using the create-next-app command-line tool.

Steps:

  • Navigate to Workspace: Open PowerShell and change to your desired workspace directory:
    cd C:\path\to\your\projects # or e.g., cd ~/projects
  • Create Next.js Project: Replace my-nextra-docs-site with your preferred project name:
    npx create-next-app@latest my-nextra-docs-site
  • Configuration Prompts (Follow these recommendations):
    • Would you like to use TypeScript? Yes (Strongly recommended for type safety and better tooling)
    • Would you like to use ESLint? Yes (For code linting and quality)
    • Would you like to use Tailwind CSS? Yes (For utility-first CSS styling)
    • Would you like to use src/ directory? No (Keeps the structure simpler with app/ at the root for this guide)
    • Would you like to use App Router? Yes (Required for Nextra 4.0)
    • Customize the default import alias (@/*)? No (The default @/* is generally fine)
  • Navigate into Project Directory:
    cd my-nextra-docs-site

Justification: create-next-app provides an optimized, pre-configured Next.js project structure. Selecting TypeScript, ESLint, and Tailwind CSS from the outset establishes a robust development environment. The App Router is a core requirement for Nextra 4.0, as detailed in the Nextra documentation.

4. Install Nextra Dependencies

Add Nextra and its Docs theme to your project.

Dependency Check (before installation, this would be empty):

  • Command (to check after installation):
    Get-Content package.json | Select-String '"nextra":' Get-Content package.json | Select-String '"nextra-theme-docs":'
  • Expected (after installation, versions might vary): "nextra": "^4.x.x", "nextra-theme-docs": "^4.x.x"

Installation:

  • Command:
    npm install nextra nextra-theme-docs
  • Verify: Check your package.json to confirm the dependencies have been added.

Justification: These packages are essential for Nextra’s functionality: nextra provides the core framework capabilities, and nextra-theme-docs supplies the pre-built documentation theme.

5. Configure Next.js for Nextra (next.config.mjs)

Integrate Nextra into the Next.js build process by modifying the Next.js configuration file.

Steps:

  • Locate/Create File: Find or create next.config.mjs in your project root.
  • Modify Configuration:
    // next.config.mjs import nextra from 'nextra'; const withNextra = nextra(); /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, experimental: { turbopack: { resolveAlias: { 'next-mdx-import-source-file': './mdx-components.tsx', }, }, }, }; export default withNextra(nextConfig);

Justification: The withNextra function wraps your Next.js configuration, enabling Nextra to process MDX files. The resolveAlias for Turbopack addresses potential MDX component resolution issues, as noted in the Nextra documentation.

6. Set Up MDX Components File (mdx-components.tsx)

This file allows custom React components for Markdown elements.

Steps:

  • Create File: Create mdx-components.tsx in the project root.
  • Add Boilerplate Code:
    // mdx-components.tsx import type { MDXComponents } from 'mdx/types'; import { useMDXComponents as getThemeMDXComponents } from 'nextra-theme-docs'; const themeComponents = getThemeMDXComponents(); export function useMDXComponents(components: MDXComponents): MDXComponents { return { ...themeComponents, ...components, }; }

Justification: This file integrates Nextra’s theme components and allows global customization of Markdown rendering, as per the Nextra MDX components guide.

7. Create Root Layout & Theme Config (app/layout.tsx)

Define the main HTML structure and configure the Nextra Docs theme.

Steps:

  • Locate/Edit File: Open app/layout.tsx.
  • Replace Contents:
    // app/layout.tsx import type { ReactNode } from 'react'; import { Footer, Layout, Navbar, LastUpdated } from 'nextra-theme-docs'; import { Head, Search } from 'nextra/components'; import { getPageMap } from 'nextra/page-map'; import type { PageMapItem } from 'nextra'; import { Inter } from 'next/font/google'; import type { Metadata } from 'next'; import 'nextra-theme-docs/style.css'; import './globals.css'; const inter = Inter({ subsets: ['latin'] }); export const metadata: Metadata = { title: { default: 'Your Project Title', template: '%s | Your Project Title', }, description: 'Comprehensive documentation for Your Awesome Project.', }; const GitHubIcon = () => ( <svg fill="currentColor" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg"> <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/> </svg> ); const navbarConfig = ( <Navbar logo={<b>Your Project</b>} projectLink="https://github.com/your-org/your-repo" > <a href="https://github.com/your-org/your-repo" target="_blank" rel="noopener noreferrer" aria-label="GitHub" className="nx-p-2 nx-text-current"> <GitHubIcon /> </a> </Navbar> ); const footerConfig = ( <Footer className="text-sm text-gray-500 dark:text-gray-400"> Copyright © {new Date().getFullYear()} Your Company or Project Name. All Rights Reserved. </Footer> ); const searchConfig = ( <Search placeholder="Search documentation..." /> ); export default async function RootLayout({ children }: { children: ReactNode }) { const pageMap: PageMapItem[] = await getPageMap('/'); return ( <html lang="en" dir="ltr" suppressHydrationWarning className={inter.className}> <Head> </Head> <body> <Layout navbar={navbarConfig} footer={footerConfig} search={searchConfig} pageMap={pageMap} docsRepositoryBase="https://github.com/your-org/your-repo/tree/main" editLink="Edit this page on GitHub →" feedback={{ content: 'Questions or feedback? Let us know →', labels: 'feedback', }} sidebar={{ defaultMenuCollapseLevel: 1, autoCollapse: true, }} toc={{ backToTop: true, }} > {children} </Layout> </body> </html> ); }

Justification: This layout.tsx establishes the global HTML structure and integrates Nextra’s <Layout> component, configured with props for navigation and theme features, as per the Nextra layout guide.

8. Adding Content Structure (app/ directory and _meta.js)

Organize your documentation content using folders within the app directory.

Steps & Example:

  • Homepage: app/page.mdx
    --- title: Project Guide Overview description: Learn how to effectively use this awesome project with our comprehensive guide. asIndexPage: true --- import { Cards, Card } from 'nextra/components' # Project Guide This guide covers all the main features and provides instructions on how to get started and use the project effectively. <Cards> <Card title="Installation Steps" href="./guide/installation/" arrow={true} /> <Card title="Core Features" href="./guide/features/" arrow={true} /> </Cards>
  • Create a “Guide” Section:
    • Create folder: app/guide/
    • Create sub-page: app/guide/installation/page.mdx
      --- title: Installation Instructions description: Step-by-step guide to installing the project. --- # Installation Follow these steps to install...
  • Configure Navigation:
    • app/_meta.js:
      // app/_meta.js export default { index: { title: 'Home', type: 'page' }, guide: 'User Guide', };
    • app/guide/_meta.js:
      // app/guide/_meta.js export default { index: 'Overview', installation: "Installation Steps", features: "Core Features" };

Justification: This file-system-based routing with _meta.js files organizes content and generates navigation, as per the Nextra file conventions guide.

9. Setting Up Search with Pagefind

Enable client-side search using Pagefind.

Installation:

  • Command:
    npm install --save-dev pagefind
  • Verify: Check package.json for "pagefind": "^1.x.x".

Configuration:

  • Update package.json scripts:
    { "scripts": { "dev": "next dev", "build": "next build", "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind", "start": "next start", "lint": "next lint" } }
  • Update .gitignore:
    # .gitignore _pagefind/ public/_pagefind/

Justification: Pagefind creates a static search index, and the <Search /> component uses it, as outlined in the Nextra search documentation.

10. Running Your Site Locally

Commands:

  • Development Mode:
    npm run dev
    Access at http://localhost:3000.
  • Production Mode:
    npm run build npm run start

Justification: Local testing ensures all configurations work before deployment.

11. Customization Options

Common Customizations:

  • Dark Mode: In app/layout.tsx, set nextThemes={{ forcedTheme: 'dark' }}.
  • Global Styling: Override in app/globals.css:
    /* app/globals.css */ :root { --nextra-primary-hue: 210deg; --nextra-primary-saturation: 100%; }

Justification: These options allow tailoring the site, as per the Nextra customization guide.

12. Deployment Strategies

Vercel Deployment:

  • Steps:
    • Import project in Vercel Dashboard.
    • Configure with default Next.js settings.
    • Deploy and access via the provided URL.

Cloudflare Pages Deployment:

  • Steps:
    • Connect to Git in Cloudflare Dashboard.
    • Set build command: npm run build, output directory: .next.
    • Enable nodejs_compat flag in Settings > Functions > Compatibility Flags.

Comparison Table:

FeatureVercel (Recommended)NetlifyCloudflare Pages
Next.js Native SupportExcellentVery GoodGood
App Router / RSCExcellentVery GoodGood
Build PerformanceVery GoodGoodExcellent
CDN PerformanceExcellentVery GoodExcellent
Free TierGenerousGenerousVery Generous

Justification: Vercel offers optimized Next.js support, while Cloudflare Pages provides high performance with the nodejs_compat flag, as per the Cloudflare Pages documentation.