Dark Mode with Next.js

Enable light and dark themes in Next.js using the class strategy Vinyaas tokens expect. Default follows the device preference.

Vinyaas writes CSS variables for light and dark. Dark styles apply when html has the dark class. Choose another guide from Dark Mode.

Default = system preference

Until the visitor picks light or dark, follow prefers-color-scheme. Do not write a stored preference on first visit — only persist after an explicit toggle.

ts
const stored = localStorage.getItem("vinyaas-theme");
const dark =
  stored === "dark" ||
  (stored !== "light" &&
    window.matchMedia("(prefers-color-scheme: dark)").matches);
document.documentElement.classList.toggle("dark", dark);

Theme tokens

After vinyaas init, your CSS entry (preferred: app/globals.css) includes light defaults and a .dark block. Components read those variables — you do not need a separate component theme package.

Toggle the class

Flip appearance by toggling dark on the document element:

ts
document.documentElement.classList.toggle("dark");

Persist the choice in localStorage (and optionally a cookie) so navigations and reloads keep the same mode.

Next.js wiring

Prefer App Router. Add suppressHydrationWarning on <html> so a before-paint theme script can set class="dark" without a hydration mismatch.

<html lang="en" suppressHydrationWarning> <body>{children}</body> </html>

Run a small inline script before paint that reads the saved preference or falls back to prefers-color-scheme, then toggles dark on document.documentElement. Keep a client toggle that writes the same preference for later visits.