reactjsnext.jsimportradixradix-ui

Radix UI + Next.js Light/Dark Mode Toggle


I'm trying to implement a light vs dark mode toggle for my Next app. I'm using the radix ui component library for my styling. I'm a little stuck trying to figure out the logic to make this happen. How can I add this functionality to my Navbar if I have to declare the theme inside of my layout.tsx file?

layout.tsx: layout

NavBar.tsx: navbar


Solution

  • Step 1: Install next-themes

    npm install next-themes
    

    Step 2: Create a theme provider

    "use client"
    
    import * as React from "react"
    import { ThemeProvider } from "next-themes"
    
    export function ThemeProvider({ children, ...props }) {
      return <ThemeProvider {...props}>{children}</ThemeProvider>
    }
    

    Step 3: Wrap your root layout

    import { ThemeProvider } from "@/components/theme-provider"
    
    export default function RootLayout({ children }) {
      return (
        <>
          <html lang="en" suppressHydrationWarning>
            <head />
            <body>
              <ThemeProvider
                attribute="class"
                defaultTheme="system"
                enableSystem
                disableTransitionOnChange
              >
                {children}
              </ThemeProvider>
            </body>
          </html>
        </>
      )
    }
    

    Step 4: Add a mode toggle

    "use client"
    
    import * as React from "react"
    import { useTheme } from "next-themes"
    
    export function NavBar() {
    
      const { theme, setTheme } = useTheme()
      const toggleMode = () => setTheme(theme == 'light' ? 'dark' : 'light')
      
      return (
        <>
        {/* Your code for the navbar */}
          <button onClick={toggleMode}> Toggle mode </button>
        </>
      )
    }