A modern documentation site theme for Nextra built with Tailwind CSS v3
nextra-theme-docs-v3 is a standalone documentation theme that provides everything you need to build a modern, beautiful documentation website. It's a fork of the official nextra-theme-docs adapted to use Tailwind CSS v3 instead of v4, making it compatible with projects that haven't migrated to Tailwind v4.
- Responsive Design - Mobile-first, fully responsive layout
- Dark Mode - Built-in dark mode with system preference detection
- Search - Integrated search functionality
- Navigation - Automatic table of contents, sidebar, and pagination
- Internationalization - Full i18n support with locale switching
- Customizable - Extensive theme configuration options
- GitHub Integration - Edit links, feedback links, and issue tracking
- Performance - Optimized for performance with Tailwind CSS v3
- Accessibility - WCAG compliant with proper semantic HTML
- Top navigation bar with logo and menu
- Collapsible sidebar with page tree
- Table of contents (TOC) with scroll spy
- Previous/next page navigation
- Theme switcher (light/dark/system)
- Locale switcher for i18n
- "Edit this page" link
- "Feedback" link
- Last updated timestamp
- Back to top button
- Banner component for announcements
- Custom footer support
Create a new Next.js project and install the required dependencies:
# Create a new Next.js app
npx create-next-app@latest my-docs
cd my-docs
# Install Nextra and the theme
npm install nextra nextra-theme-docs-v3Note: If you already have a Next.js project, you only need to install
nextraandnextra-theme-docs-v3.
Create or update next.config.mjs:
import nextra from "nextra";
const withNextra = nextra({
theme: "nextra-theme-docs-v3",
themeConfig: "./theme.config.jsx",
});
export default withNextra({
// Next.js configuration options
});Add the following scripts to your package.json:
{
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
}Create app/layout.jsx:
import { Footer, Layout, Navbar } from "nextra-theme-docs-v3";
import { Banner, Head } from "nextra/components";
import { getPageMap } from "nextra/page-map";
import "nextra-theme-docs-v3/style.css";
export const metadata = {
title: "My Documentation",
description: "Documentation built with Nextra and Tailwind CSS v3",
};
const banner = <Banner storageKey="banner">Nextra v3 is released!</Banner>;
const navbar = (
<Navbar
logo={<b>My Docs</b>}
projectLink="https://github.com/yourusername/your-repo"
/>
);
const footer = <Footer>MIT {new Date().getFullYear()} © My Docs.</Footer>;
export default async function RootLayout({ children }) {
return (
<html lang="en" dir="ltr" suppressHydrationWarning>
<Head>{/* Your additional head tags */}</Head>
<body>
<Layout
banner={banner}
navbar={navbar}
pageMap={await getPageMap()}
docsRepositoryBase="https://github.com/yourusername/your-repo/tree/main"
footer={footer}
>
{children}
</Layout>
</body>
</html>
);
}Create mdx-components.jsx:
import { useMDXComponents } from "nextra-theme-docs-v3";
export function useMDXComponents(components) {
return useMDXComponents(components);
}Create app/page.mdx:
# Welcome to My Documentation
This is my first documentation page built with [Nextra](https://nextra.site) and Tailwind CSS v3!
## Features
- Easy to use
- Fast and responsive
- Beautiful out of the boxnpm run devVisit http://localhost:3000 to see your documentation site!
The theme is configured through the <Layout> component props in your root layout.
| Prop | Type | Default | Description |
|---|---|---|---|
pageMap |
PageMapItem[] |
required | Page map from getPageMap() |
docsRepositoryBase |
string |
"https://github.com/shuding/nextra" |
Docs repository URL |
children |
ReactNode |
required | Page content |
import { Banner } from "nextra/components";
const banner = <Banner storageKey="my-banner">Important announcement!</Banner>;| Prop | Type | Description |
|---|---|---|
storageKey |
string |
localStorage key for dismissal |
children |
ReactNode |
Banner content |
import { Navbar } from "nextra-theme-docs-v3";
const navbar = (
<Navbar
logo={<b>My Logo</b>}
projectLink="https://github.com/user/repo"
chatLink="https://discord.gg/..."
/>
);| Prop | Type | Description |
|---|---|---|
logo |
ReactNode |
Logo or brand name |
projectLink |
string |
GitHub repository URL |
chatLink |
string |
Discord or chat link |
feedbackComponent |
ReactNode |
Custom feedback component |
import { Footer } from "nextra-theme-docs-v3";
const footer = <Footer>MIT © 2024</Footer>;<Layout
sidebar={{
defaultOpen: true,
toggleButton: true,
defaultMenuCollapseLevel: 2,
autoCollapse: false,
}}
>
{children}
</Layout>| Option | Type | Default | Description |
|---|---|---|---|
defaultOpen |
boolean |
true |
Show sidebar by default |
toggleButton |
boolean |
true |
Show sidebar toggle button |
defaultMenuCollapseLevel |
number |
2 |
Folder collapse level (1 = all collapsed) |
autoCollapse |
boolean |
false |
Auto-collapse inactive folders |
<Layout
toc={{
float: true,
title: "On This Page",
backToTop: "Scroll to top",
extraContent: <div>Extra content</div>,
}}
>
{children}
</Layout>| Option | Type | Default | Description |
|---|---|---|---|
float |
boolean |
true |
Float TOC next to content |
title |
ReactNode |
'On This Page' |
TOC section title |
backToTop |
ReactNode |
'Scroll to top' |
Back to top button text |
extraContent |
ReactNode |
- | Extra content below TOC |
<Layout
navigation={{
prev: true,
next: true,
}}
>
{children}
</Layout>| Option | Type | Default | Description |
|---|---|---|---|
prev |
boolean |
true |
Show previous page link |
next |
boolean |
true |
Show next page link |
<Layout
darkMode={true}
nextThemes={{
defaultTheme: "system",
storageKey: "theme",
disableTransitionOnChange: true,
}}
>
{children}
</Layout>| Option | Type | Default | Description |
|---|---|---|---|
darkMode |
boolean |
true |
Enable dark mode toggle |
nextThemes.defaultTheme |
string |
'system' |
Default theme ('light', 'dark', 'system') |
nextThemes.storageKey |
string |
'theme' |
localStorage key |
nextThemes.disableTransitionOnChange |
boolean |
true |
Disable transitions on theme change |
<Layout
themeSwitch={{
dark: "Dark",
light: "Light",
system: "System",
}}
>
{children}
</Layout><Layout
editLink="Edit this page"
// or disable: editLink={null}
>
{children}
</Layout><Layout
feedback={{
content: "Question? Give us feedback",
labels: "feedback",
link: "https://github.com/user/repo/issues/new",
}}
>
{children}
</Layout>| Option | Type | Default | Description |
|---|---|---|---|
content |
ReactNode |
'Question? Give us feedback' |
Link text |
labels |
string |
'feedback' |
GitHub issue labels |
link |
string |
auto-generated | Custom feedback URL |
import { LastUpdated } from "nextra-theme-docs-v3";
<Layout lastUpdated={<LastUpdated locale="en">Last updated:</LastUpdated>}>
{children}
</Layout>;<Layout
i18n={[
{ locale: "en", name: "English" },
{ locale: "es", name: "Español" },
{ locale: "fr", name: "Français" },
]}
>
{children}
</Layout>import { Search } from "nextra/components";
<Layout
search={<Search />}
// or disable: search={null}
>
{children}
</Layout>;For advanced search setup, see the Nextra Search Documentation.
Configure individual pages using MDX front matter:
---
title: Page Title
description: Page description for SEO
sidebarTitle: Custom Sidebar Title
---
# Page ContentCreate _meta.js files to organize your documentation:
// app/docs/_meta.js
export default {
index: "Introduction",
"getting-started": "Getting Started",
guides: {
title: "Guides",
items: {
installation: "Installation",
configuration: "Configuration",
},
},
"--": {
type: "separator",
title: "Advanced",
},
api: "API Reference",
};Create a global CSS file and import it in your layout:
/* styles/globals.css */
:root {
--nextra-primary-hue: 212;
--nextra-primary-saturation: 100%;
--nextra-primary-lightness: 53%;
}// app/layout.jsx
import "../styles/globals.css";Create custom MDX components in mdx-components.jsx:
import { useMDXComponents } from "nextra-theme-docs-v3";
const components = {
// Override or add components
h1: ({ children }) => <h1 className="text-4xl font-bold my-4">{children}</h1>,
};
export function useMDXComponents(providerComponents) {
return useMDXComponents({
...providerComponents,
...components,
});
}Access current page configuration:
import { useConfig } from "nextra-theme-docs-v3";
function MyComponent() {
const { title, frontMatter } = useConfig();
return <div>{title}</div>;
}Access theme configuration:
import { useThemeConfig } from "nextra-theme-docs-v3";
function MyComponent() {
const config = useThemeConfig();
return <div>{config.docsRepositoryBase}</div>;
}Access and control sidebar menu state:
import { useMenu, setMenu } from "nextra-theme-docs-v3";
function MyComponent() {
const menu = useMenu();
const toggle = () => setMenu(!menu);
return <button onClick={toggle}>Toggle Menu</button>;
}Available for import:
import {
Layout,
Navbar,
Footer,
ThemeSwitch,
LocaleSwitch,
LastUpdated,
NotFoundPage,
Link,
} from "nextra-theme-docs-v3";If you're migrating from the official nextra-theme-docs (Tailwind v4) to this v3 version:
-
Update package installation:
npm uninstall nextra-theme-docs npm install nextra-theme-docs-v3
-
Update imports:
// Before import { Layout } from "nextra-theme-docs"; import "nextra-theme-docs/style.css"; // After import { Layout } from "nextra-theme-docs-v3"; import "nextra-theme-docs-v3/style.css";
-
Update Next.js config:
// Before const withNextra = nextra({ theme: "nextra-theme-docs", // ... }); // After const withNextra = nextra({ theme: "nextra-theme-docs-v3", // ... });
-
No configuration changes needed - All props and options remain the same!
The package includes full TypeScript definitions:
import type {
LayoutProps,
ThemeConfig,
PageMapItem,
} from "nextra-theme-docs-v3";See the Nextra documentation for a live example built with this theme.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT © Ardian Eka Candra
- Based on nextra-theme-docs by Shu Ding
- Built with Nextra and Tailwind CSS v3