What's this article about?
This is about how to change shared styles, like fonts and the primary color, when building a UI with Joy UI.
For one-off changes, you can just use the sx prop, but for changing things globally, you use extendTheme.
Here's how it works.
Let's get into it.
Environment
- React TS
- Joy UI v5.0.0-beta.49
- As of 2025.01.20
How to do it
First, create a themes directory (or similar) as shown below, and create a theme.ts file inside it.
Let's try filling in the contents like this, for example.
The key point is using extendTheme.
// src/themes/theme.ts
import { extendTheme } from '@mui/joy/styles';
const theme = extendTheme({
colorSchemes: {
light: {
palette: {
primary: {
50: '#e3f2fd',
100: '#bbdefb',
200: '#90caf9',
300: '#64b5f6',
400: '#42a5f5',
500: '#2196f3',
600: '#1e88e5',
700: '#1976d2',
800: '#1565c0',
900: '#0d47a1',
},
},
},
},
fontFamily: {
display: 'Roboto, sans-serif',
body: 'Arial, sans-serif',
},
});
export default theme;Next, import this into App.tsx.
Wrap everything in CssVarsProvider. Then, if you pass the theme.ts you created earlier as the theme, the style gets applied to every component underneath it.
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import './styles/App.css';
import { RecoilRoot } from 'recoil';
// theme
import { CssVarsProvider } from '@mui/joy';
import theme from './themes/theme';
// component
// 省略
function App() {
return (
<RecoilRoot>
<CssVarsProvider theme={theme}>
<Router>
<Header />
<Analytics />
<Routes>
<Route path="/" element={<Top />} />
</Routes>
</Router>
</CssVarsProvider>
</RecoilRoot>
);
}
export default App;And that's it — now you can apply changes across the entire project!
Nice work!!
Reference
↓ The official documentation
https://mui.com/joy-ui/customization/approaches
Bonus
I also set it up so the font switches depending on whether you're on mac, windows, or another OS.
//
// このファイルは、JoyUI のテーマを定義するファイルです。
// created date: 2025.01.20
// created by: coiai
//
import { extendTheme } from '@mui/joy/styles';
// OSごとのフォント設定
const getSerifFont = () => {
const platform = navigator.platform.toLowerCase();
if (platform.includes('win')) {
return 'Yu Mincho, serif'; // Windows の場合は遊明朝
} else if (platform.includes('mac')) {
return 'Hiragino Mincho Pro, serif'; // Mac の場合はヒラギノ明朝
} else {
return 'serif'; // その他のOSはデフォルトのセリフ体
}
};
const theme = extendTheme({
colorSchemes: {
light: {
palette: {
primary: {
50: '#e3f2fd',
100: '#bbdefb',
200: '#90caf9',
300: '#64b5f6',
400: '#42a5f5',
500: '#2196f3',
600: '#1e88e5',
700: '#1976d2',
800: '#1565c0',
900: '#0d47a1',
},
},
},
},
fontFamily: {
display: getSerifFont(), // 見出し用フォント
body: getSerifFont(), // 本文用フォント
},
});
export default theme;
