Dark mode in Remix

Install next-themes

Start by installing next-themes:

npm install next-themes

Create a theme provider

Create a theme-provider.tsx file and paste the below code in it

import { ThemeProvider as NextThemesProvider } from "next-themes";
import { type ThemeProviderProps } from "next-themes/dist/types";

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}

Add the provider

Wrap your application with the ThemeProvider component.

import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "@remix-run/react";
import { ThemeProvider } from "./theme-provider";
import "./tailwind.css";

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <ThemeProvider enableSystem={true} attribute="class">
          {children}
        </ThemeProvider>
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

export default function App() {
  return <Outlet />;
}

Create a toggle

Create a toggle button to switch between light and dark themes.

import { useTheme } from "next-themes";
import { MoonIcon, SunIcon } from "@astraicons/react/linear";
import { Button } from "@/app/common/astra-ui/button";

const ThemeButton = () => {
  const { theme, setTheme } = useTheme();

  return (
    <Button
      className="flex-shrink-0 p-2.5 ring-0 focus:ring-0 focus:border-none text-grayscale-textIcon-title"
      variant="ghost"
      size="md"
      onClick={() => setTheme(theme === "light" ? "dark" : "light")}
    >
      <SunIcon className="size-6 transition-all scale-100 rotate-0 dark:-rotate-90 dark:scale-0" />
      <MoonIcon className="absolute size-6 transition-all scale-0 rotate-90 dark:rotate-0 dark:scale-100" />
      <span className="sr-only">Toggle theme</span>
    </Button>
  );
};

export default ThemeButton;

Expand

Now you can use this switch in your application to toggle between light and dark themes.