Skip to main content

How to use Material UI with Docusaurus

· 5 min read
Reaper

This blog post explains how to add Material UI to Docusaurus, use the MUI components, and how to combine the themes so that switching between dark and light themes affect both Docusaurus and MUI.

Docusaurus with MUI meme

This post assumes you already have Docusaurus installed and started up using your favorite development environment.

Install Material UI

Install the MUI core.

npm install @mui/material @emotion/react @emotion/styled

Using Material UI Components

Once installed you can use the MUI components and other tools like normal. Import them, and use them in your .jsx and .mdx code. I used them to style the homepage.

example.jsx
import Container from "@mui/system/Container";
import Card from "@mui/material/Card";
import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";

<Grid container justifyContent="center" sx={{ paddingBottom: 8 }}>
<Grid item xs={12}>
<Card
variant="outlined"
sx={{
textAlign: "center",
boxShadow: 3,
}}
>
<Typography variant="h4">This is an example</Typography>
</Card>
</Grid>
</Grid>;

Material UI CSS Theme Variables

For integrating MUI theme with Docusaurus, I opted for using the MUI experimental CSS Theme Variables. It allows you to create both your light and dark colors in the same theme, and switch between them using MUIs setMode from useColorScheme.

Create MUI Color Theme

I first created my color scheme in a file I named index.jsx at /src/components/MuiTheme/index.jsx. Like MUIs createTheme, you only need to specify the variables you wish to change from default. A simplified theme is below.

/src/components/MuiTheme/index.jsx
import { experimental_extendTheme as extendTheme } from "@mui/material/styles";

// General MUI theme
const extTheme = extendTheme({
colorSchemes: {
light: {
palette: {
primary: {
main: "hsl(240, 48%, 47%)",
},
background: {
paper: "hsl(240, 15%, 95%)",
},
},
},
dark: {
palette: {
primary: {
main: "hsl(240, 90%, 70%)",
},
background: {
paper: "hsl(210, 3%, 15%)",
},
},
},
},
});

export default extTheme;

Applying MUI Theme to Site

We need to import the MUI theme, and wrap it around the entire website. This can be done by swizzing the <Root>. For this, we simply create a file Root.js at /src/theme/Root.js. Then place the below code in that file.

/src/theme/Root.js
import React from "react";
import { getInitColorSchemeScript } from "@mui/material/styles";
import { Experimental_CssVarsProvider as CssVarsProvider } from "@mui/material/styles";
import theme from "@site/src/components/MuiTheme";

export default function Root({ children }) {
return (
<>
{getInitColorSchemeScript()}
<CssVarsProvider theme={theme}>{children}</CssVarsProvider>
</>
);
}

Matching Docusaurus and MUI Theme

Now we need to be able to determine what color mode Docusaurus is in, and sync that with our MUI theme.

Swizzling ColorModeToggle

In order to match the color schemes, I made use of Docusaurus' swizzling feature again, to wrap their ColorModeToggle and add my own functionality. This component is labeled "Safe" to swizzle, and wrapping is the best option. See the Docusaurus docs on Swizzling if you want more information about this functionality.

In short, the command I ran was:

npm run swizzle @docusaurus/theme-classic ColorModeToggle -- --wrap

This creates the ColorModeToggle wrapper at /src/theme/ColorModeToggle/index.js.

Syncing the Themes

Then inside the ColorModeToggle index.js you can add the mode switching functionality.

/src/theme/ColorModeToggle/index.js
import React, { useEffect } from "react";
import ColorModeToggle from "@theme-original/ColorModeToggle";
import { useColorScheme } from "@mui/material/styles";

export default function ColorModeToggleWrapper(props) {
// MUI color mode setting
const { setMode } = useColorScheme();

// "value" holds the color theme. Either "light" or "dark"
const { value } = props;

// change mode based on "value" prop
// "dark" or "light" are also used for MUI
useEffect(() => {
setMode(value);
}, [value]);

return (
<>
<ColorModeToggle {...props} />
</>
);
}

Using MUI Them Elsewhere

Now that the themes sync, we can use that synced theme anywhere on the site! Including this docs and blog section. Since the entire site is wrapped in Root.js, no extra steps are needed. You can even reference your theme variables from within the components. Below I added using the primary.main color for the text (which changes between dark and light mode).

This blog post
import Container from "@mui/system/Container";
import Card from "@mui/material/Card";
import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
import { Experimental_CssVarsProvider as CssVarsProvider } from "@mui/material/styles";
import theme from "@site/src/components/MuiTheme";

<Grid container justifyContent="center" sx={{ paddingBottom: 4 }}>
<Grid item xs={12}>
<Card
variant="outlined"
sx={{
textAlign: "center",
boxShadow: 3,
}}
>
<Typography variant="h4" sx={{ color: "primary.main" }}>
This is an example
</Typography>
</Card>
</Grid>
</Grid>;

This is an example

Try changing the color theme using the Docusaurus button. Notice how the above example changes color depending on which color theme is chosen?

Theme Synced Meme

Further Documentation

For further details on MUIs CSS theme variables, see their documentation.

Go forth and do great things.