Dynamic Theming with CSS Variables in Next.js
Show how to use CSS custom properties (variables) within a Next.js application to allow dynamic theming.
// pages/_app.js
import '../styles/globals.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp;
This is the custom App component (_app.js) where you can include global CSS for the Next.js application.
// styles/globals.css
:root {
--primary-color: #0070f3;
--background-color: #fff;
--text-color: #333;
}
[data-theme='dark'] {
--primary-color: #9e9e9e;
--background-color: #000;
--text-color: #fff;
}
body {
background-color: var(--background-color);
color: var(--text-color);
}
In the globals.css file, CSS variables are set for the default light theme. A dark theme is also defined using a data attribute selector where variables are reassigned different values.
// components/ToggleThemeButton.js
import { useState, useEffect } from 'react';
const ToggleThemeButton = () => {
const [theme, setTheme] = useState('light');
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
}, [theme]);
const toggleTheme = () => {
setTheme(theme === 'light' ? 'dark' : 'light');
};
return (
<button onClick={toggleTheme}>
Toggle Theme
</button>
);
};
export default ToggleThemeButton;
This component, ToggleThemeButton.js, includes a button that allows the user to toggle the theme. The useEffect hook updates the `data-theme` attribute on the document's root element whenever the theme state changes, causing a re-render with the new theme variables.
// pages/index.js
import ToggleThemeButton from '../components/ToggleThemeButton';
export default function Home() {
return (
<div>
<h1>Welcome to Next.js!</h1>
<ToggleThemeButton />
</div>
);
}
In the main page component (pages/index.js), the ToggleThemeButton component is imported and used to render a button that lets the user toggle between light and dark themes.