· Engineering · 2 min read

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

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

Florian, Founder

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 docs 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.

Set up your project

The best way to set up 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 separate Nextra Layout for both your blog and docs. This way you can load the content separately but also control the final visual result independent of each other.

At pipe0 we set this up the following way:

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>
  );
}
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 separately 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.

Next-gen enrichment & search.

Build revenue systems that scale. For humans, agents, and apps. Replace tools like Clay, n8n, Hightouch, etc.

selectedRun
InputHDFind work email
NameWork email
Ada ByrneHa.byrne@acme.io
Leo CostaDl.costa@northbeam.co
Mia ChenRunning...
New empty row
Using pipe0 at work?