Skip to Content
How to Use the Docs and Blog Theme in the Same App with Nextra

How to Use the Docs and Blog Theme in the Same App with Nextra

Nextra is a framework on top of Next.js, that lets you build content-focused websites. It combines features from Next.js and lets you create markdown-based static sites easily and straightforwardly.

Nextra offers two themes: Blog theme and docs theme.

Just as you cannot have an app in light and dark theme at the same time, it is equally impossible to use both the blog theme and the docs theme at the same time.

Both themes define conflicting MDX components that overwrite each other at critical points.

Trying to use both themes at the same time will lead to conflicts with missing Context Providers and missing components.

How to have a blog and docs in the same app with Nextra

It is still possible to have a blog and an app within the same app. Applications like the SWR Docs are built in this manner. The application supports both docs and a blog from the same repository. The code is open source.

Another example is the pipe0 docs.

Setup your project

The best way to setup a blog and a docs page from the same app is to move the nextra Layout component out of the root layout component and have a seperate Nextra Layout for both your blog and docs. This way you you can load the content seperately but also control the final visual result indipendent of each other.

At pipe0 we set this up the following way:

src/app/blog/layout.tsx
import { Layout } from "nextra-theme-docs"; import { appInfo } from "@/lib/const"; import { getPageMap } from "nextra/page-map"; import { PropsWithChildren } from "react"; export default async function RootLayout({ children }: PropsWithChildren) { return ( <Layout pageMap={await getPageMap("/blog")} sidebar={{ defaultOpen: false, toggleButton: false }} editLink={null} feedback={{ content: null }} > <div> {children} </div> </Layout> ); }
src/app/resources/layout.tsx
import { Layout } from "nextra-theme-docs"; import { getPageMap } from "nextra/page-map"; import { PropsWithChildren } from "react"; export default async function RootLayout({ children }: PropsWithChildren) { return ( <Layout pageMap={await getPageMap("/resources")} editLink={null} feedback={{ content: null }} > {children} </Layout> ); }

With this setup we store our content for /resources seperately from the blog posts and end up with a consistent visual experience for both blog and docs.

Read more about this approach in this GitHub issue.

logo-dark
Add clay-like 🌈 data enrichment to your application. Fast.
Last updated on