Como usar next-themes no novo next 13 e tailwindcss

    felipebdn
    há 10 meses
    0

    Passo 1: Configuração inicial do projeto

    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

    Passo 2: Instalação das dependências

    yarn add next-themes

    Passo 3: Alterar configuração do Tailwindcss

    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: [], }

    Passo 4: Criando arquivos de configuração.

    • Na pasta 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') }

    Passo 5: Importar o ThemeProvider do next-themes dentro do arquivo layout do projeto next.

    Para isso temos que nos atentar em duas coisas:

    • o next-themes é uma lib que funciona de forma 'client side'.
    • e o arquivo 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.

    Passo 6: Importar os 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> ) }

    Passo 7: Usar o hook useTheme do next-themes para alterar o tama da aplicação

    Para 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> }