Tema escuro con Nextjs
ven., 3 de feb. de 2023
Hai moitas formas de facer a xestión de temas de estilos en React e Nextjs, pero todas elas pasan por ter un array/obxeto con todos os estilos de cada un dos distintos temas, tamén
outra das formas é usar variables de css ou scss estas últimas están en cada vez en máis deshuso. Eu, en particular vou usar variables de css e fixar un tema por defecto no meu _document . Por que aquí ?
Por que _document execútase en servidor non como _app que o fai en cliente e se usas un useEffect para setear o teu tema por defecto ou detectar o que ten o usuario no seu sistema operativo,
no tempo que se tarda en facer esta comprobación e engadilo, pode darse un parpadeo nos estilos da paxina. Iso pode resultar estraño.
Eu fíxeno así:
1 - Variables do css
--white-color: 255, 255, 255;
--color-available-arrow: 95, 91 98;
--blog-header: 53, 45, 55;
--blog-nav: 204, 202, 219;
--blog-header: 255, 255, 255;
2 - Fixar tema por defecto
const Document = (props: Props) => {
<Html lang={props.__NEXT_DATA__.locale} data-theme="light">
3 - Custom hook pra cambiar o tema
import React from 'react';
const useDarkMode = (): { theme: null | 'dark' | 'light'; toggleTheme: () => void; scheme: typeof scheme } => {
const [theme, setTheme] = React.useState<null | 'dark' | 'light'>(null);
if (typeof window !== 'undefined' && window.matchMedia) {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handler = (event: MediaQueryListEvent) => {
setTheme(event.matches ? scheme.dark : scheme.light);
mediaQuery.addEventListener('change', handler);
return () => mediaQuery.removeEventListener('change', handler);
if (typeof window !== 'undefined' && theme) {
document.documentElement.setAttribute('data-theme', theme);
const toggleTheme = () => {
setTheme(theme === scheme.dark ? scheme.light : scheme.dark);
return { theme, scheme, toggleTheme };
export default useDarkMode;
4 - Usar o hook
const { formatMessage: f } = useIntl();
<div className={styles.container}>
<section className={styles.confg}>
alt={f({ id: 'settings.langAlt' })}
name={f({ id: theme === dark ? 'settings.dark' : 'settings.light' })}
<section className={styles.confg}></section>
Para facer a proba en vivo, podes cambiar o tema no teu sistema operativo e verás que o meu sitio web actualízase automaticamente ou tamén podes ir ao meu pagina de configuración e cambiar o tema.
Todo o código no meu repositorio de github, se che gusta este proxecto, ou se o contido axudouche en algo podes recompensarme cunha ⭐️, Grazas!