Styling Your Site with Next.js and MUI: Creating a Dynamic Theme Switcher

Styling Your Site with Next.js and MUI: Creating a Dynamic Theme Switcher

Hello, devs! ✌🏾

As promised, I’m back to posting more frequently. Today, we’re kicking off a series on using Material-UI with Next.js to create a simple switch between light and dark themes.

Starting a Next.js Project

Getting started is straightforward. Just follow the steps in the Next.js documentation:

npx create-next-app@latest

Once Next.js is installed, let’s clean up the directory. Remove the files globals.css and page.module.css that we won’t use.

In your page.tsx, the code should look like this:

export default function Home() {
return <div>Hello world</div>
}

And don’t forget to remove the import import “./globals.css”; in the layout.tsx file.

Installing Material-UI (MUI)

To get started with MUI, visit the Getting started section of the documentation. You can use npm, yarn, or pnpm for installation. Here, I’ll use pnpm:

pnpm add @mui/material @emotion/react @emotion/styled

After installation, let’s test by adding a button to the page to see if everything is correct:

import Button from @mui/material/Button;

export default function Home() {
return (
<>
<div>Hello world</div>
<br />
<Button>CLick here</Button>
</>
)
}

If everything is installed properly, your browser will display it like this:

Remember to start the Next.js server with pnpm dev.

Creating a Theme

Let’s create a theme.ts file in src/styles and set up a function to toggle the colors based on the chosen theme (light or dark):

import { PaletteMode } from @mui/material;

const primaryDark = #6a1b9a;
const primaryLight = #4a148c;

export const getDesignTokens = (mode: PaletteMode) => ({
palette: {
mode,
…(mode === light
? {
primary: {
main: primaryLight,
},
}
: {
// palette values for dark mode
primary: {
main: primaryDark,
},
})
}
})

For example, if we opt for the dark theme, we’ll use the lighter purple since the background will already be dark, and vice versa.

Implementing Theme Switch

In layout.tsx, add the following imports:


import { PaletteMode } from @mui/material
import CssBaseline from @mui/material/CssBaseline
import { ThemeProvider, createTheme } from @mui/material/styles

Set up a state to manage the theme and store it using useMemo:

const [mode, setMode] = useState<PaletteMode>(light)
const theme = useMemo(() => {
return createTheme(getDesignTokens(mode))
}, [mode])

Add the Material-UI provider to manage theme changes:


<html lang=en>
<body className={inter.className}>
<ThemeProvider theme={theme}>
<CssBaseline />
{children}
</ThemeProvider>
</body>
</html>

Try toggling the state between light and dark:


Note: If you are using Next.js 14, include ‘use client’ at the beginning of the layout.tsx file.

Switching Themes with a Button

Create a button to easily switch the theme:

<Button onClick={() => setMode(mode === light ? dark : light)}>
Toggle mode
</Button>

And voilà! Your site is now ready to switch between two modes.

Conclusion

Ideally, we should encapsulate all the theme logic in a provider to keep the layout clean and organized. This is just a simple example to kick-start your next project using Material-UI.

Got more tips? Questions or want to share another approach? Feel free to comment below!

Thanks for your attention, and see you next time!

GIT REPOSITORY

Leave a Reply

Your email address will not be published. Required fields are marked *