How to Create Custom Pages in Docusaurus Beyond Docs and Blog

Create custom pages in Docusaurus by adding Markdown, MDX, or React files to the src/pages directory, where the built-in @docusaurus/plugin-content-pages plugin automatically generates standalone routes for each file.

Docusaurus treats pages as a distinct content type separate from documentation and blog posts. According to the facebook/docusaurus source code, any file placed in the configured pages directory becomes a standalone route, compiled through the MDX loader and rendered outside the docs/blog navigation structure.

How the Pages Plugin Works

The @docusaurus/plugin-content-pages plugin powers custom page generation. In src/packages/docusaurus-plugin-content-pages/src/index.ts, the pluginContentPages function registers the plugin, initializes the MDX loader, and sets up file watching for the source directory. The plugin processes files with extensions .md, .mdx, .js, .jsx, .ts, and .tsx, compiling them into React components via @docusaurus/mdx-loader while extracting front-matter metadata like title and image.

Default configuration values are defined in src/packages/docusaurus-plugin-content-pages/src/options.ts, where path: 'src/pages' specifies the source folder and routeBasePath: '/' sets the URL base. The createAllRoutes function in src/packages/docusaurus-plugin-content-pages/src/routes.ts then maps each discovered file to a router entry, converting relative file paths into public URLs.

Configuring the Pages Directory

When using the classic preset, customize the pages plugin through the preset options in docusaurus.config.js. The pages field accepts the Options type from @docusaurus/plugin-content-pages, as implemented in src/packages/docusaurus-preset-classic/src/options.ts.

// docusaurus.config.js
module.exports = {
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        pages: {
          path: 'src/custom-pages',          // Folder to scan
          routeBasePath: '/my-pages',        // URL prefix
          include: ['**/*.mdx', '**/*.tsx'], // File patterns
        },
      },
    ],
  ],
};

Set pages: false to disable the plugin entirely.

Creating Different Types of Custom Pages

Docusaurus supports multiple formats for custom pages, allowing you to choose the right tool for static content, interactive components, or dynamic applications.

Simple Markdown Pages

For content that requires no React components, create a .md file in the pages directory. The repository includes an example at src/examples/classic/src/pages/markdown-page.md demonstrating this pattern:

---
title: About Us
slug: /about
---

# About Us

Welcome to our site! This page is pure Markdown and does not need any React code.

With the default routeBasePath: '/', this file automatically serves at /about.

MDX Pages with React Components

For interactive content, use MDX to import and render React components within Markdown:

import MyForm from '@site/src/components/MyForm';

export const frontMatter = {
  title: 'Contact',
};

# Get in Touch

<MyForm />

The MDX loader configured in src/packages/docusaurus-plugin-content-pages/src/index.ts compiles this into a React page component, passing the front-matter title to the default MDXPage layout.

JavaScript and TypeScript Pages

For full control over layouts, data fetching, or authentication, create React components directly in the pages folder:

import React from 'react';
import Layout from '@theme/Layout';
import useAuth from '@site/src/hooks/useAuth';

export default function Dashboard() {
  const {user, isAuthenticated} = useAuth();

  if (!isAuthenticated) {
    return <Layout>Signing in…</Layout>;
  }

  return (
    <Layout title="Dashboard">
      <h1>Hello, {user.name}!</h1>
    </Layout>
  );
}

Placing this file at src/pages/dashboard.tsx creates a route at /dashboard that renders your custom component.

Customizing Routes and File Patterns

The plugin configuration supports three primary parameters defined in src/packages/docusaurus-plugin-content-pages/src/options.ts:

  • path: The source directory to scan (default: src/pages)
  • routeBasePath: The URL prefix for all generated pages (default: /)
  • include: Glob patterns determining which files to process (default: standard web extensions)

Adjusting these values changes URL generation. For example, configuring path: 'src/custom' with routeBasePath: '/pages' makes src/custom/help.mdx accessible at /pages/help instead of the root.

Summary

  • Custom pages in Docusaurus are generated by @docusaurus/plugin-content-pages, which scans a configurable directory and creates routes for every supported file type.
  • The default setup uses src/pages as the source and serves files at the site root, but you can override path and routeBasePath in docusaurus.config.js to change these locations.
  • Supported formats include Markdown (.md), MDX (.mdx), and React components (.js, .jsx, .ts, .tsx), all processed through the MDX loader to extract front-matter and compile JSX.
  • Files map directly to URLs based on their relative path, with front-matter metadata controlling page titles, descriptions, and explicit slugs.

Frequently Asked Questions

Where does Docusaurus look for custom pages by default?

By default, Docusaurus scans the src/pages directory as specified in src/packages/docusaurus-plugin-content-pages/src/options.ts. Any file with extensions .md, .mdx, .js, .jsx, .ts, or .tsx found in this folder automatically becomes a standalone page route.

Can I disable the pages plugin if I only need documentation and blog features?

Yes. Set pages: false within the classic preset options in docusaurus.config.js. This prevents the @docusaurus/plugin-content-pages plugin from loading, removing custom page functionality while preserving docs and blog capabilities.

How do I change the URL structure for all custom pages?

Modify the routeBasePath option in your preset configuration. The route generation logic in src/packages/docusaurus-plugin-content-pages/src/routes.ts uses this value to prefix all page URLs. Setting routeBasePath: '/site' moves all pages from the root to /site/page-name.

What file extensions are supported for custom pages?

The plugin accepts .md, .mdx, .js, .jsx, .ts, and .tsx files by default. Restrict or expand this list using the include configuration option, such as include: ['**/*.mdx', '**/*.tsx'] to process only MDX and TypeScript files.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →