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

react-next-theme

Package Overview
Dependencies
Maintainers
0
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-next-theme - npm Package Compare versions

Comparing version 1.1.0 to 1.1.1

12

package.json
{
"name": "react-next-theme",
"version": "1.1.0",
"version": "1.1.1",
"type": "module",

@@ -22,5 +22,13 @@ "description": "A simple and flexible theme switcher for React and Next.js, supporting light and dark modes with localStorage and system preferences.",

"light-mode",
"dark theme",
"light theme",
"theme-toggle",
"react-theme",
"next-theme"
"next-theme",
"theme provider",
"React dark mode",
"Next.js dark mode",
"custom themes",
"user preference theme",
"dark mode toggle"
],

@@ -27,0 +35,0 @@ "author": "Mesu",

449

README.md

@@ -1,258 +0,302 @@

Sure! Here's the complete **`README.md`** file, including instructions for both **npm** and **yarn**, detailed usage for **React**, **Next.js (Pages Router and App Router)**, and the **CSS** you provided.
# react-next-theme
`react-next-theme` is a lightweight, customizable theme switcher for React and Next.js applications, supporting light and dark modes. It detects system preferences, applies the theme instantly, and prevents a white flash on page load.
## Key Features
- **Light and Dark Mode Support**: Allows seamless theme switching.
- **System Preference Detection**: Automatically detects and applies the user’s system theme preference.
- **No White Flash on Load**: Instantly applies the theme for a smooth user experience.
- **Easy Setup**: Works seamlessly in React and Next.js (supports both Page and App Routers).
---
# react-next-theme
## Common Setup Instructions
`react-next-theme` is a simple and flexible theme switcher for React and Next.js applications, supporting light and dark modes. It provides a seamless solution for managing themes across your applications with automatic theme detection based on system preferences and local storage.
1. **Install the Package**
## Features
```bash
npm install react-next-theme
```
- Supports **light** and **dark** modes.
- Automatically respects system preferences for dark mode.
- Easy to integrate in **React** and **Next.js** applications (both **App Router** and **Pages Router**).
- Prevents the white flash on page load by applying the correct theme immediately.
- Customizable and extendable for your project needs.
or
## Installation
```bash
yarn add react-next-theme
```
You can install the package via **npm** or **yarn**.
2. **Create CSS for Theme Variables**
### Using npm
Define theme colors in a CSS file. You can either create a `theme.css` file in the `public` folder or add these styles directly to `index.css` (React) or `globals.css` (Next.js).
```bash
npm install react-next-theme
```
```css
/* Light and dark mode theme variables */
:root {
--background-color: white;
--text-color: black;
}
### Using yarn
html[data-theme='dark'] {
--background-color: black;
--text-color: white;
}
```bash
yarn add react-next-theme
```
body {
background-color: var(--background-color);
color: var(--text-color);
transition: background-color 0.3s, color 0.3s;
}
```
---
## Basic Setup
## React Setup (Create React App or Vite)
### 1. Add Theme-Specific CSS Variables
1. **Add Theme Script to `public/index.html`**
To ensure the theme is correctly applied to your application, include the following CSS in your global styles (`index.css` or `globals.css` depending on your setup):
you can change color as you want.
To ensure the theme is applied before the app mounts, create a `theme-script.js` file in the `public` folder with the following code:
```css
:root {
--background-color: white;
--text-color: black;
}
```js
// public/theme-script.js
(function() {
const storedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = storedTheme || (prefersDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
})();
```
html[data-theme='dark'] {
--background-color: black;
--text-color: white;
}
Then, link the script in `public/index.html`:
body {
background-color: var(--background-color);
color: var(--text-color);
transition: background-color 0.3s, color 0.3s;
}
```
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React App</title>
This CSS sets the background and text colors based on the `data-theme` attribute applied to the `<html>` element.
<!-- Link to theme initialization script -->
<script src="%PUBLIC_URL%/theme-script.js"></script>
---
<!-- Link to CSS file -->
<link rel="stylesheet" href="%PUBLIC_URL%/theme.css" />
</head>
<body>
<div id="root"></div>
</body>
</html>
```
## Usage in **React** (Create React App or Vite)
2. **Wrap Your App with `ThemeProvider` in `src/index.js`**
### 1. Inject Theme Initialization Script and Style
Wrap your main app component with `ThemeProvider` to enable dynamic theme switching.
To prevent a white flash on page load, you need to inject a script that applies the correct theme before React mounts. Modify your **`public/index.html`** or **`index.html`** file:
```js
// src/index.js or src/main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { ThemeProvider } from 'react-next-theme';
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React App</title>
ReactDOM.render(
<ThemeProvider>
<App />
</ThemeProvider>,
document.getElementById('root')
);
```
<!-- Insert the theme initialization style of the avobe style -->
<!-- <link rel="stylesheet" href="insert css file link"> -->
3. **Use the `useTheme` Hook in Components**
<!-- Insert the theme initialization script -->
<script>
(function() {
const storedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = storedTheme || (prefersDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
})();
</script>
</head>
<body>
<div id="root"></div>
</body>
</html>
```
Use the `useTheme` hook to toggle themes in any component. Here’s an example for a button in `App.js`:
### 2. Use `ThemeProvider` in `src/index.js` or `src/main.js`
```js
// src/App.js
import React from 'react';
import { useTheme } from 'react-next-theme';
Wrap your app with the `ThemeProvider` to handle dynamic theme switching:
function App() {
const { theme, toggleTheme } = useTheme();
```js
// src/index.js or src/main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { ThemeProvider } from 'react-next-theme';
return (
<div>
<h1>{theme === 'light' ? 'Light Mode' : 'Dark Mode'}</h1>
<button onClick={toggleTheme}>
{theme === 'light' ? 'Switch to Dark Mode' : 'Switch to Light Mode'}
</button>
</div>
);
}
ReactDOM.render(
<ThemeProvider>
<App />
</ThemeProvider>,
document.getElementById('root')
);
```
export default App;
```
### 3. Use the `useTheme` Hook in Your Components
---
you can change the button or modify as your need
## Next.js (Page Router) Setup
```js
// src/App.js
import React from 'react';
import { useTheme } from 'react-next-theme';
1. **Theme Initialization Script in `_document.js`**
function App() {
const { theme, toggleTheme } = useTheme();
To apply the theme before Next.js renders the app, you can either use `getThemeScript` from `react-next-theme` or link a separate script file.
return (
<div>
<h1>{theme === 'light' ? 'Light Mode' : 'Dark Mode'}</h1>
<button onClick={toggleTheme}>
{theme === 'light' ? 'Switch to Dark Mode' : 'Switch to Light Mode'}
</button>
</div>
);
}
- **Option A: Use `getThemeScript` directly**:
export default App;
```
```js
// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document';
import { getThemeScript } from 'react-next-theme';
---
export default function Document() {
return (
<Html lang="en">
<Head>
<link rel="stylesheet" href="/theme.css" />
<script dangerouslySetInnerHTML={{ __html: getThemeScript() }} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
```
## Usage in **Next.js (Pages Router)**
- **Option B: Use an external script file**:
### 1. Inject Theme Script in `_document.js`
1. Create `public/theme-script.js`:
To prevent the white flash, you need to inject the theme initialization script using Next.js' `_document.js` file:
```js
// public/theme-script.js
(function() {
const storedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = storedTheme || (prefersDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
})();
```
```js
// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document';
import { getThemeScript } from 'react-next-theme';
2. Reference the script file in `_document.js`:
export default function Document() {
return (
<Html>
<Head>
{/* Inject the theme initialization script */}
<script dangerouslySetInnerHTML={{ __html: getThemeScript() }} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
```
```js
// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document';
import Script from 'next/script';
### 2. Wrap Your App with `ThemeProvider` in `_app.js`
export default function Document() {
return (
<Html lang="en">
<Head>
<link rel="stylesheet" href="/theme.css" />
</Head>
<body>
<Script src="/theme-script.js" strategy="beforeInteractive" />
<Main />
<NextScript />
</body>
</Html>
);
}
```
```js
// pages/_app.js
import { ThemeProvider } from 'react-next-theme';
2. **Wrap Your App with `ThemeProvider` in `_app.js`**
function MyApp({ Component, pageProps }) {
return (
<ThemeProvider>
<Component {...pageProps} />
</ThemeProvider>
);
}
Wrap the main component with `ThemeProvider` to handle theme switching:
export default MyApp;
```
```js
// pages/_app.js
import { ThemeProvider } from 'react-next-theme';
### 3. Use `useTheme` Hook in Components
function MyApp({ Component, pageProps }) {
return (
<ThemeProvider>
<Component {...pageProps} />
</ThemeProvider>
);
}
```js
// components/Header.js
import { useTheme } from 'react-next-theme';
export default MyApp;
```
function Header() {
const { theme, toggleTheme } = useTheme();
---
return (
<header>
<button onClick={toggleTheme}>
{theme === 'light' ? 'Switch to Dark Mode' : 'Switch to Light Mode'}
</button>
</header>
);
}
## Next.js (App Router) Setup
export default Header;
```
1. **Theme Initialization in `app/layout.js`**
---
In Next.js 13+ (App Router), you can initialize the theme by either using `getThemeScript` or an external script file.
## Usage in **Next.js (App Router)**
- **Option A: Use `getThemeScript` directly**:
### 1. Inject Theme Script in `layout.js`
```js
// app/layout.js
import { ThemeProvider, getThemeScript } from 'react-next-theme';
For **Next.js 13** (App Router), modify the **`app/layout.js`** file to inject the theme initialization script:
export const metadata = {
title: 'My App',
};
```js
// app/layout.js
import { getThemeScript } from 'react-next-theme';
export default function RootLayout({ children }) {
return (
<html lang="en">
<head>
<link rel="stylesheet" href="/theme.css" />
<script dangerouslySetInnerHTML={{ __html: getThemeScript() }} />
</head>
<body>
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>
);
}
```
export const metadata = {
title: 'My App',
};
- **Option B: Use an external script file**:
export default function RootLayout({ children }) {
return (
<html lang="en">
<head>
{/* Inject the theme initialization script */}
<script dangerouslySetInnerHTML={{ __html: getThemeScript() }} />
</head>
<body>
{children}
</body>
</html>
);
}
```
1. Create `public/theme-script.js` as follows:
### 2. Wrap the App with `ThemeProvider`
```js
// public/theme-script.js
(function() {
const storedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = storedTheme || (prefersDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
})();
```
In **Next.js (App Router)**, wrap your entire app with the `ThemeProvider`:
2. Reference the script file in `app/layout.js`:
```js
// app/layout.js
import { ThemeProvider } from 'react-next-theme';
```js
// app/layout.js
import { ThemeProvider } from 'react-next-theme';
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<ThemeProvider>
{children}
</ThemeProvider>
);
}
```
export const metadata = {
title: 'My App',
};
### 3. Use `useTheme` Hook in Components
export default function RootLayout({ children }) {
return (
<html lang="en">
<head>
<link rel="stylesheet" href="/theme.css" />
</head>
<body>
<Script src="/theme-script.js" strategy="beforeInteractive" />
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>
);
}
```
---
## Using the `useTheme` Hook to Toggle Themes
To toggle themes in components, use the `useTheme` hook.
```js

@@ -269,2 +313,4 @@ // components/Header.js

{theme === 'light' ? 'Switch to Dark Mode' : 'Switch to Light Mode'}
</button>

@@ -277,13 +323,24 @@ </header>

```
---
## Using a Script File Instead of Inlining the Script
### **Recommendation**
For simplicity and a clean setup, **using `getThemeScript` is often the best choice**, especially for projects where ease of integration and minimal file management are priorities. It’s also ideal for teams that prefer not to have extra files in `public` or are working on smaller projects.
However, for **larger projects or production-level apps** where caching and modularity are important, **using `public/theme-script.js`** can improve load times slightly and centralize your theme logic.
In summary:
- **Smaller projects or simpler setups** → `getThemeScript`
- **Larger projects or production-focused apps** → `public/theme-script.js`
Let me know if you’d like further customization in setup based on these considerations!
### Using a Script File Instead of Inlining the Script
If you prefer to use an external script file, you can place the theme initialization script inside the **`public/`** folder and reference it using the `<Script>` component in Next.js:
### 1. Create `public/react-next-theme-script.js`:
### 1. Create `public/theme-script.js`:
```js
// public/react-next-theme-script.js
// public/theme-script.js
(function() {

@@ -302,3 +359,3 @@ const storedTheme = localStorage.getItem('theme');

<Script src="/react-next-theme-script.js" strategy="beforeInteractive" />
<Script src="/theme-script.js" strategy="beforeInteractive" />
```

@@ -305,0 +362,0 @@

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