Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nextjs-themes

Package Overview
Dependencies
Maintainers
0
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nextjs-themes

Unleash the Power of React Server Components! Use multiple themes on your site with confidence, without losing any advantages of React Server Components.

  • 4.0.0-alpha.2
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1K
decreased by-49.15%
Maintainers
0
Weekly downloads
 
Created
Source

Next.js Themes

test Maintainability codecov Version Downloads npm bundle size Contact me on Codementor

Version 3 Short Notes: Version 3.0 brings minor API changes along with major performance improvements and fixes. We have minimized changes to existing APIs.

Note: react18-themes will now be maintained as nextjs-themes, as server-specific APIs are no longer needed.

🤟 👉 Unleash the Power of React Server Components

  • ✅ Perfect dark mode in 2 lines of code
  • ✅ Fully Treeshakable (import from nextjs-themes/client/component)
  • ✅ Full TypeScript Support
  • ✅ Unleash the full power of React 18 Server components

Exampand following to see more features.

Motivation and Key Features:

This project was inspired by next-themes. Unlike next-themes, nextjs-themes doesn't require wrapping everything in a provider, allowing you to take full advantage of React 18 Server Components. Additionally, it offers more features and control over your app's theming.

  • ✅ Perfect dark mode in 2 lines of code
  • ✅ Fully Treeshakable (import from nextjs-themes/client/component)
  • ✅ Designed for excellence
  • ✅ Full TypeScript Support
  • ✅ Unleash the full power of React 18 Server components
  • ✅ System setting with prefers-color-scheme
  • ✅ Themed browser UI with color-scheme
  • ✅ Support for Next.js 13 & Next.js 14 appDir
  • ✅ No flash on load (for all - SSG, SSR, ISG, Server Components)
  • ✅ Sync theme across tabs and windows
  • ✅ Disable flashing when changing themes
  • ✅ Force pages to specific themes
  • ✅ Class and data attribute selector
  • ✅ Manipulate theme via useTheme hook
  • ✅ Documented with Typedoc (Docs)
  • ✅ Use combinations of [data-th=""] and [data-color-scheme=""] for dark/light variants of themes
  • ✅ Use [data-csp=""] to style based on colorSchemePreference.

Check out the live example.

Installation

$ pnpm add nextjs-themes

or

$ npm install nextjs-themes

or

$ yarn add nextjs-themes

Want Lite Version?

npm bundle size Version Downloads

$ pnpm add nextjs-themes-lite

or

$ npm install nextjs-themes-lite

or

$ yarn add nextjs-themes-lite

Note: r18gs is a peer dependency

Usage

SPA (e.g., Vite, CRA) and Next.js pages directory (No server components)

To add dark mode support, modify _app.js as follows:

import { ThemeSwitcher } from "nextjs-themes";

function MyApp({ Component, pageProps }) {
  return (
    <>
      <ThemeSwitcher forcedTheme={Component.theme} />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

⚡🎉Boom! Dark mode is ready in just a couple of lines!

With Next.js app router (Server Components)

Update app/layout.jsx to add ThemeSwitcher from nextjs-themes:

// app/layout.jsx
import { ThemeSwitcher } from "nextjs-themes";

export default function Layout({ children }) {
  return (
    <html lang="en">
      <head />
      <body>
        <ThemeSwitcher />
        {children}
      </body>
    </html>
  );
}

Woohoo! Multiple theme modes with Server Components support!

HTML & CSS

Next.js app supports dark mode, including System preference with prefers-color-scheme. The theme is synced between tabs, modifying the data-theme attribute on the html element:

:root {
  --background: white;
  --foreground: black;
}

[data-theme="dark"] {
  --background: black;
  --foreground: white;
}

Images

Show different images based on the current theme:

import Image from "next/image";
import { useTheme } from "nextjs-themes";

function ThemedImage() {
  const { resolvedTheme } = useTheme();
  const src = resolvedTheme === "light" ? "/light.png" : "/dark.png";
  return <Image src={src} width={400} height={400} />;
}

export default ThemedImage;

useTheme

The useTheme hook provides theme information and allows changing the theme:

import { useTheme } from "nextjs-themes";

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

  return (
    <div>
      The current theme is: {theme}
      <button onClick={() => setTheme("light")}>Light Mode</button>
      <button onClick={() => setTheme("dark")}>Dark Mode</button>
    </div>
  );
};

The useTheme hook returns the following object:

interface UseThemeYield {
  theme: string;
  darkTheme: string;
  lightTheme: string;
  colorSchemePref: ColorSchemeType;
  systemColorScheme: ResolvedColorSchemeType;
  resolvedColorScheme: ResolvedColorSchemeType;
  resolvedTheme: string;
  setTheme: (theme: string) => void;
  setDarkTheme: (darkTheme: string) => void;
  setLightTheme: (lightTheme: string) => void;
  setThemeSet: (themeSet: { darkTheme: string; lightTheme: string }) => void;
  setColorSchemePref: (colorSchemePref: ColorSchemeType) => void;
  toggleColorScheme: (skipSystem?: boolean) => void;
  setForcedTheme: (forcedTheme: string) => void;
  setForcedColorScheme: (forcedColorScheme: ColorSchemeType) => void;
}

Force per page theme and color-scheme

Next.js App Router

import { ForceTheme } from "nextjs-themes/force-theme";

function MyPage() {
  return (
    <>
      <ForceTheme theme="my-theme" />
      ...
    </>
  );
}

export default MyPage;

If you are using TypeScript and have not set nodeResolution to Bundler or Node16 or NodeNext, you need to import from nextjs-themes/client/force-theme

Next.js Pages Router

For the pages router, you have two options. The first option is the same as the app router, and the second option, which is compatible with next-themes, involves adding the theme property to your page component like this:

function MyPage() {
  return <>...</>;
}

MyPage.theme = "my-theme";

export default MyPage;

Similarly, you can force a color scheme. This will apply your defaultDark or defaultLight theme, which can be configured via hooks.

With Styled Components and any CSS-in-JS

Next Themes works with any library. For Styled Components, createGlobalStyle in your custom App:

// pages/_app.js
import { createGlobalStyle } from "styled-components";
import { ThemeSwitcher } from "nextjs-themes";

const GlobalStyle = createGlobalStyle`
  :root {
    --fg: #000;
    --bg: #fff;
  }

  [data-theme="dark"] {
    --fg: #fff;
    --bg: #000;
  }
`;

function MyApp({ Component, pageProps }) {
  return (
    <>
      <GlobalStyle />
      <ThemeSwitcher forcedTheme={Component.theme} />
      <Component {...pageProps} />
    </>
  );
}

With Tailwind

In tailwind.config.js, set the dark mode property to class:

// tailwind.config.js
module.exports = {
  darkMode: "class",
};

⚡🎉Ready to use dark mode in Tailwind!

Caution: Your class must be "dark", which is the default value used in this library. Tailwind requires the class name "dark" for dark-theme.

Use dark-mode specific classes:

<h1 className="text-black dark:text-white">

Migration

Refer to the migration guide.

Docs

Typedoc

🤩 Don't forget to star this repo!

Want a hands-on course for getting started with Turborepo? Check out React and Next.js with TypeScript

FAQ

Do I need to use CSS variables with this library?

No. You can hard code values for every class:

.my-class {
  color: #555;
}

[data-theme="dark"] .my-class {
  color: white;
}

Why is resolvedTheme and resolvedColorScheme necessary?

To reflect the System theme preference and forced theme/colorScheme pages in your UI. For instance, buttons or dropdowns indicating the current colorScheme should say "system" when the System colorScheme preference is active.

resolvedTheme is useful for modifying behavior or styles at runtime:

const { resolvedTheme, resolvedColorScheme } = useTheme();
const background = getBackground(resolvedTheme);

<div style={{ color: resolvedColorScheme === 'dark' ? white : black, background }}>

Without resolvedTheme, you would only know the theme is "system", not what it resolved to.

Repo stats

License

This library is licensed under the MPL-2.0 open-source license.

Please consider enrolling in our courses or sponsoring our work.


with 💖 by Mayank Kumar Chaudhari

Keywords

FAQs

Package last updated on 24 Jun 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc