ClassName generator
Configure classname generation at build time.
This API is introduced in @mui/material
(v5.0.5) as a replacement of deprecated createGenerateClassName
.
Setup
By default, Material UI generates a global class name for each component slot. For example, <Button>Text</Button>
generates html as:
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span>
<span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>MuiButton-root MuiButton-text MuiButton-textPrimary MuiButton-sizeMedium MuiButton-textSizeMedium MuiButtonBase-root css-1ujsas3<span class="token punctuation">"</span></span>
<span class="token punctuation">></span></span>
Text
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span>
To customize all the class names generated by Material UI components, create a separate JavaScript file to use the ClassNameGenerator
API.
<span class="token comment">// create a new file called `MuiClassNameSetup.js` at the root or src folder.</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> unstable_ClassNameGenerator <span class="token keyword">as</span> ClassNameGenerator <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/className'</span><span class="token punctuation">;</span>
ClassNameGenerator<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span>
<span class="token comment">// Do something with the componentName</span>
<span class="token punctuation">(</span><span class="token parameter">componentName</span><span class="token punctuation">)</span> <span class="token operator">=></span> componentName<span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
and then import the file at the root of the index before any @mui/*
imports.
<span class="token keyword">import</span> <span class="token string">'./MuiClassNameSetup'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> Button <span class="token keyword">from</span> <span class="token string">'@mui/material/Button'</span><span class="token punctuation">;</span>
<span class="token comment">// ...other component imports</span>
<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Button</span></span><span class="token punctuation">></span></span>Text<span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Button</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
Here are some configuration examples:
Change class name prefix
<span class="token comment">// MuiClassNameSetup.js</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> unstable_ClassNameGenerator <span class="token keyword">as</span> ClassNameGenerator <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/className'</span><span class="token punctuation">;</span>
ClassNameGenerator<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">componentName</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">foo-bar-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>componentName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
As a result, the HTML result changes to the following:
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span>
<span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>foo-bar-MuiButton-root foo-bar-MuiButton-text foo-bar-MuiButton-textPrimary foo-bar-MuiButton-sizeMedium foo-bar-MuiButton-textSizeMedium foo-bar-MuiButtonBase-root css-1ujsas3<span class="token punctuation">"</span></span>
<span class="token punctuation">></span></span>
Button
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span>
Rename component class name
Every Material UI component has ${componentName}-${slot}
classname format. For example, the component name of Chip
is MuiChip
, which is used as a global class name for every <Chip />
element. You can remove/change the Mui
prefix as follows:
<span class="token comment">// MuiClassNameSetup.js</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> unstable_ClassNameGenerator <span class="token keyword">as</span> ClassNameGenerator <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/className'</span><span class="token punctuation">;</span>
ClassNameGenerator<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">componentName</span><span class="token punctuation">)</span> <span class="token operator">=></span> componentName<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">'Mui'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Now, the Mui
class is gone.
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span>
<span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Chip-root Chip-filled Chip-sizeMedium Chip-colorDefault Chip-filledDefault css-mttbc0<span class="token punctuation">"</span></span>
<span class="token punctuation">></span></span>
Chip
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
Caveat
ClassNameGenerator.configure
must be called before any Material UI components import.you should always use
[component]Classes
for theming/customization to get the correct generated class name.<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">import { outlinedInputClasses } from '@mui/material/OutlinedInput'; </span></span> <span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">const theme = createTheme({ </span><span class="token prefix unchanged"> </span><span class="token line"> components: { </span><span class="token prefix unchanged"> </span><span class="token line"> MuiOutlinedInput: { </span><span class="token prefix unchanged"> </span><span class="token line"> styleOverrides: { </span><span class="token prefix unchanged"> </span><span class="token line"> root: { </span></span><span class="token deleted-sign deleted"><span class="token prefix deleted">-</span><span class="token line"> '& .MuiOutlinedInput-notchedOutline': { </span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line"> // the result will contain the prefix. </span><span class="token prefix inserted">+</span><span class="token line"> [`& .${outlinedInputClasses.notchedOutline}`]: { </span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> borderWidth: 1, </span><span class="token prefix unchanged"> </span><span class="token line"> } </span><span class="token prefix unchanged"> </span><span class="token line"> } </span><span class="token prefix unchanged"> </span><span class="token line"> } </span><span class="token prefix unchanged"> </span><span class="token line"> } </span><span class="token prefix unchanged"> </span><span class="token line"> } </span><span class="token prefix unchanged"> </span><span class="token line">});</span></span>
This API should only be used at build-time.
The configuration is applied to all of the components across the application. You cannot target a specific part of the application.
Framework examples
Always create an initializer file to hoist the ClassNameGenerator
call to the top.
<span class="token comment">// create a new file called `MuiClassNameSetup.js` at the root or src folder.</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> unstable_ClassNameGenerator <span class="token keyword">as</span> ClassNameGenerator <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/className'</span><span class="token punctuation">;</span>
ClassNameGenerator<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span>
<span class="token comment">// Do something with the componentName</span>
<span class="token punctuation">(</span><span class="token parameter">componentName</span><span class="token punctuation">)</span> <span class="token operator">=></span> componentName<span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
Then import the file in the main JavaScript source based on the framework.
Next.js
Import the initializer in /pages/_app.js
.
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">import './MuiClassNameSetup';
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">import * as React from 'react';
</span><span class="token prefix unchanged"> </span><span class="token line">import PropTypes from 'prop-types';
</span><span class="token prefix unchanged"> </span><span class="token line">import Head from 'next/head';
</span></span>
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">export default function MyApp(props) {
</span><span class="token prefix unchanged"> </span><span class="token line"> const { Component, pageProps } = props;
</span></span>
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> return (
</span><span class="token prefix unchanged"> </span><span class="token line"> <Component {...pageProps} />
</span><span class="token prefix unchanged"> </span><span class="token line"> );
</span><span class="token prefix unchanged"> </span><span class="token line">}</span></span>
Create React App
Import the initializer in /src/index.js
.
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">import './MuiClassNameSetup';
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">import * as React from 'react';
</span><span class="token prefix unchanged"> </span><span class="token line">import * as ReactDOM from 'react-dom';
</span><span class="token prefix unchanged"> </span><span class="token line">import App from './App';
</span></span>
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">ReactDOM.render(<App />);</span></span>
Gatsby
Import the initializer in gatsby-ssr.js
at the root folder.
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">import './MuiClassNameSetup';
</span></span>
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">export const wrapPageElement = ({ element }) => {
</span><span class="token prefix unchanged"> </span><span class="token line"> return element;
</span><span class="token prefix unchanged"> </span><span class="token line">};</span></span>