Custom Theme Per Doc Page with Docusaurus 2

1k views Asked by At

I have been playing around with custom themes on Docusaurus 2, and I have successfully extended components like DocItem by "wrapping theme components". I am wondering if Docusaurus 2 supports different doc themes per page. For example, I would like to create a 2 column layout theme, and select a few doc pages where I would use this theme, while the others would continue to use the default Docusaurus theme.

I am imagining something in the doc front matter like:

---
id: doc1
theme: twocol
title: Style Guide
sidebar_label: Style Guide
slug: /
---

I haven't found anything yet when running around the Docusaurus documentation, so hoping to get a quick answer here.

1

There are 1 answers

0
Shawn Tabrizi On BEST ANSWER

After getting a good hint from the Docusaurus discord channel, I figured out how to do this. I created the following ThemeSelector component:

// Select a theme using the `theme` front matter

import React from 'react';
import OriginalDocItem from "@theme-original/DocItem";
import TwoColDocItem from "../TwoColDocItem"

export default function ThemeSelector(props) {
    const { content: DocContent } = props;
    const { frontMatter: { theme } } = DocContent;

    switch (theme) {
        case "twocol":
            return <TwoColDocItem {...props} />
        default:
            return <OriginalDocItem {...props} />
    }
}

This simply selects the appropriate layout based on the front matter of the doc file.

The TwoColDocItem layout looks like this:

// Two column layout for react

import React from 'react';
import OriginalDocItem from "@theme-original/DocItem";
import styles from "./style.module.css"

export default function TwoColDocItem(props) {
    return (
        <>
            <div className={styles.row}>
                <div className={styles.col}>
                    <OriginalDocItem {...props} />
                </div>
                <div className={styles.col}>
                    <div>Second Col</div>
                </div>
            </div>
        </>
    );
}