Next.js

为您的 Next.js 应用添加深色模式。

Dark mode

Install next-themes

Start by installing next-themes:

npm install next-themes

Create a theme provider

components/theme-provider.tsx
'use client';
 
import * as React from 'react';
import { ThemeProvider as NextThemesProvider } from 'next-themes';
 
export function ThemeProvider({
  children,
  ...props
}: React.ComponentProps<typeof NextThemesProvider>) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}

Wrap your root layout

ThemeProvider 添加到您的 root layout 中。

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

Add a mode toggle

在您的网站上放置一个模式切换按钮,用于在浅色和深色模式之间切换。

Loading...
components/mode-toggle.tsx
'use client';

import * as React from 'react';

import { MoonIcon, SunIcon } from 'lucide-react';
import { useTheme } from 'next-themes';

import { useMounted } from '@/hooks/use-mounted';
import { Button } from '@/components/plate-ui/button';

export default function ModeToggle() {
  const { setTheme, theme } = useTheme();

  const mounted = useMounted();

  return (
    <Button
      size="sm"
      variant="ghost"
      className="size-8 px-0"
      onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
    >
      {mounted && theme === 'dark' ? (
        <MoonIcon className="size-[1.2rem]" />
      ) : (
        <SunIcon className="size-[1.2rem]" />
      )}
      <span className="sr-only">Toggle theme</span>
    </Button>
  );
}