Atualmente a versão do next está na 13.4.9. Talvez quando você estiver vendo essa publicação, exista algumas diferenças, caso de algum problema consulte a documentação do next-themes
Para criar o projeto next execute esse comando no seu terminal.
yarn create next-app
yarn add next-themes
No arquivo tailwindcss.config.js
, adicione darkMode: 'class'
, esse trecho de código ficará parecido com isso
/** @type {import('tailwindcss').Config} */ module.exports = { darkMode: 'class', content: [ './src/pages/**/*.{js,ts,jsx,tsx,mdx}', './src/components/**/*.{js,ts,jsx,tsx,mdx}', './src/app/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: { backgroundImage: { 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', }, }, }, plugins: [], }
src
cria uma pasta chamada utils
e dentro dela crie um arquivo chamado themeLocalStorage.ts
, você pode dar o nome que quiser, após criar o arquivo cole esse código.export function getThemeLocalStorage() { if ( localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches) ) { document.documentElement.classList.add('dark') } else { document.documentElement.classList.remove('dark') } localStorage.theme = 'light' localStorage.theme = 'dark' localStorage.removeItem('theme') }
ThemeProvider
do next-themes
dentro do arquivo layout
do projeto next.Para isso temos que nos atentar em duas coisas:
next-themes
é uma lib que funciona de forma 'client side'.layout
está setado pra rodar 'server side', tanto é que nele existe uma constante chamada metadata
que recebe um objeto com informações daquela rota, isso existe para garantir uma otimização adequada do mecanismo de pesquisa (SEO), e esse valor de configuração só da pra ser configurado em arquivos que serão renderizados pelo server side
.então não é possível importar o ThemeProvider
diretamente no arquivo, para resolver isso podemos criar um arquivo chamado providers.tsx
dentro da pasta src/app
com esse código:
'use client' import { ThemeProvider } from "next-themes" import { ReactNode } from "react" export function Providers({children}:{children:ReactNode}){ return ( <ThemeProvider attribute="class"> {children} </ThemeProvider> ) }
esse use client
é o que declara o limite entre servidor e cliente.
Providers
dentro do layout
Ficará dessa forma:
import './globals.css' import type { Metadata } from 'next' import { Providers } from './providers' export const metadata: Metadata = { title: 'Create Next App', description: 'Generated by create next app', } export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="en"> <Providers> <body>{children}</body> </Providers> </html> ) }
useTheme
do next-themes
para alterar o tama da aplicaçãoPara isso a gente poderia fazer de varias formas, para exemplificação criaremos uma div
que ocupará a tela inteira, e colocaremos um botão para efetuar a troca do tema.
'use client' import { getThemeLocalStorage } from "@/utils/themeLocalStorage" import { useTheme } from "next-themes" import { useEffect } from "react" export default function Home() { const { setTheme, resolvedTheme } = useTheme() function handleTheme() { resolvedTheme === 'dark' ? setTheme('light') : setTheme('dark') } useEffect(() => { getThemeLocalStorage() }, []) return <div className="h-screen w-screen bg-blue-700 dark:bg-red-600"> <button onClick={handleTheme}>Mudar tema</button> </div> }