How to create a custom Material UI theme for Gatsby

material-ui, theme, gatsby, react, selfnote


Image by annca from Pixabay

** Note on 2020-06-26 **

There is a very nice customization video, React Material-UI Themes: Customize Material Components for your Project.

Been searching for easy way to customize Material UI (MUI hereafter) theme and found few online tools to help me get it done quick.

Most of steps here are for configuring Gatsby for Material UI theme but a custom MUI theme set up is easy.

1. Bootstrap a new Gatsby site

npx gatsby new site-name-here

2. Install libraries

  1. Material UI (MUI)
1npm install @material-ui/core2# or3yarn add @material-ui/core
  1. gatsby-plugin-material-ui - Gatsby plugin for SSR support
1npm install -D gatsby-plugin-material-ui2# or3yarn add -D gatsby-plugin-material-ui

3. Create a custom MUI theme

  1. Go to the Google's Material Design Color Tool site
  2. Select primary & secondary colors and copy the current URL (, which updates on color selection)
    color tool
  3. Go to https://react-theming.github.io/create-mui-theme/ and paste the URL in Paste URL here input box
  4. Now custom Theme JSON should be generated on the bottom right
    custom JSON

4. Configure MUI theme

I will create a local plugin to keep the code organized.
Refer to Creating a Local Plugin for more info

  1. Create a new local Gatsby plugins folder, ./plugins/custom-mui-theme in the project root

  2. Configure Gatsby plugin

    1. wrapRootElement.js

      • A helper module to add MUI theme context provider
      • wrapRootElement is a way to wrap the root Gatsby element. We will wrap the root element with MUI theme provider
      1import React from "react";2import { ThemeProvider } from "@material-ui/core/styles";3
      4import theme from "./theme";5
      6export const wrapRootElement = ({ element }) => {7  console.info(`theme`, theme);8  return <ThemeProvider theme={theme}>{element}</ThemeProvider>;9};
    2. gatsby-browser.js

      • To wrap the top-level element with MUI theme provider for the browser
      • We can simply export wrapRootElement in one line
      export { wrapRootElement } from "./wrapRootElement";
    3. gatsby-ssr.js

      • To wrap the top-level element with MUI theme provider on the server side
      • The implementation is the same as the browser version
      export { wrapRootElement } from "./wrapRootElement";
    4. package.json - Required for the local plugin

      • Add the plugin name in the file
      1{2  "name": "custom-mui-theme"3}
  3. Create a new folder ./plugins/custom-mui-theme/theme

  4. Create two files under the theme folder

    1. theme.json

      • Copy & paste the theme JSON file in the previous step, Createa custom MUI theme
    2. index.js

      • This is to provide the custom theme generated in Createa custom MUI theme section
      • It needs a bit of change as we need to import the JSON theme
      1import { createMuiTheme } from "@material-ui/core/styles";2import themeData from "./theme.json";3
      4const themeName = "My custom theme name";5export default createMuiTheme({ ...themeData, themeName });
  5. Configure gatsby-plugin-material-ui and add the custom-mui-theme (the latter should be below) in the project root's gatsby-config.js

1module.exports = {2  // ...3  plugins: [4    // other plugins ...5    {6      resolve: `gatsby-plugin-material-ui`,7      options: {8        stylesProvider: {9          injectFirst: true,10        },11      },12    },13    `custom-mui-theme`,14  ],15};
  • injectFirst lets us override the MUI styles with Tailwind CSS

5. Checking if the custom theme is applied

In ./src/pages/index.js, add the primary button to see if the color matches that of your custom style

1import React from "react";2
3import Button from "@material-ui/core/Button";4
5const IndexPage = () => (6  <>7    <Button color="primary" variant="contained">8      A button!9    </Button>10    <Button color="secondary" variant="contained">11      A button!12    </Button>13  </>14);15
16export default IndexPage;

You will see that the primary and secondary colors are applied according to the custom theme.


From here on, simply updating ./plugins/custom-mui-theme/theme/theme.json should update the MUI theme

6. Resources

  • A Gatsby site source created by following the steps above - https://github.com/dance2die/blog.custom-material-ui-gatsby-theme
  • Google's Material Design Color Tool: https://material.io/resources/color/
  • Create MUI Theme site
    • Home - https://react-theming.github.io/create-mui-theme/
    • Source - https://github.com/react-theming/create-mui-theme (MIT licenced)
  • Gatsby
    • gatsby-plugin-material-ui
      • Source - https://github.com/hupe1980/gatsby-plugin-material-ui
      • Documentation - https://www.gatsbyjs.org/packages/gatsby-plugin-material-ui/?=gatsby-plugin-material-ui
    • wrapRootElement - https://www.gatsbyjs.org/docs/browser-apis/#wrapRootElement
    • "Creating a Local Plugin" - https://www.gatsbyjs.org/docs/creating-a-local-plugin/
    • Plugins documentation - https://www.gatsbyjs.org/docs/plugins/
  • Material UI
    • Home - https://material-ui.com/
    • Official MUI + Gatsby sample - https://github.com/mui-org/material-ui/tree/master/examples/gatsby
    • Theming - https://material-ui.com/customization/theming/
    • Default Theme (Theme JSON overrides this) - https://material-ui.com/customization/default-theme/

Image by annca from Pixabay