Search code examples
docusaurus

Custom Theme Per Doc Page with Docusaurus 2


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.


Solution

  • 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>
            </>
        );
    }