You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+31-50
Original file line number
Diff line number
Diff line change
@@ -1,26 +1,21 @@
1
1
# next-theme-toggle
2
2
3
-
This package is based on [https://www.designcise.com/web/tutorial/how-to-create-non-flickering-dark-or-light-mode-toggle-in-next-js](https://www.designcise.com/web/tutorial/how-to-create-non-flickering-dark-or-light-mode-toggle-in-next-js).
3
+
A simple theme toggle for Next.js 13+ that allows switching between light and dark themes. Using this package would result in the following `class` and `style` attributes added to the `<html>` element:
4
4
5
-
## Goals
5
+
```html
6
+
<htmlclass="dark"style="color-scheme:dark">
7
+
```
6
8
7
-
The goal of the project is to:
9
+
You can then [use different CSS selectors to create styles for dark/light themes](https://www.designcise.com/web/tutorial/how-to-create-non-flickering-dark-or-light-mode-toggle-in-next-js-using-localstorage#adding-the-ability-to-switch-themes).
10
+
11
+
## Goals
8
12
9
13
- Provide an easy way of toggling between light and dark themes
10
14
- Auto-switch theme on page load based on system settings
11
15
- Avoid flicker on page load
12
16
- Have no unnecessary bloat
13
17
- Have very minimal configuration
14
-
15
-
## Expectations
16
-
17
-
Result of using this package will be that the following are added to the `<html>` element:
18
-
19
-
```html
20
-
<htmlclass="dark"style="color-scheme:dark">
21
-
```
22
-
23
-
After which you can [use different CSS selectors to create styles for dark/light themes](https://www.designcise.com/web/tutorial/how-to-create-non-flickering-dark-or-light-mode-toggle-in-next-js#switching-theme).
> **NOTE**: Please note that this approach relies on using cookies on client and server side, and will, therefore, cause the route to be dynamically rendered as cookies rely on request time information.
41
+
> **NOTE**: Please note that this approach relies on using `localStorage` on the client sideto store theme information.
47
42
48
43
At a bare minimum you need to do the following:
49
44
@@ -55,48 +50,26 @@ import { cookies } from 'next/headers';
The `Html` component is added for convenience. If you do not wish to use it, then you can achieve the same with the native `html` element in the following way:
You may also choose to not do this step altogether and pass `autoAntiFlicker={true}` (or just `autoAntiFlicker`) to the `ThemeProvider` component, which will automatically inject a script into DOM that takes care of this for you. For example:
All these approaches help you avoid flicker on initial page load.
98
-
99
-
> **NOTE**: Please note that using the script injection method will show the `Warning: Extra attributes from the server:class,style` warning in console in the dev environment only. This is unavoidable unfortunately, as it happens because the injected script adds additional `class` and `style` attributes to the `html` element which do not originally exist on the server-side generated page.
72
+
With this setup, the `ThemeProvider` component will automatically inject an inline script into DOM that takes care of avoiding flicker on initial page load.
100
73
101
74
2. Create a button to toggle between light and dark theme:
102
75
@@ -204,12 +177,11 @@ That's it! You should have light/dark theme toggle in your Next.js application.
204
177
205
178
You can pass the following props to `ThemeProvider`:
|`children`|`React.ReactChild`|`React.ReactChild[]`| Components to which the theme is passed down to via context. |
183
+
|`storageKey`| String | Name of the key used for storage. |
184
+
|`defaultTheme`| String | Default theme (`'light'` or `'dark'`) to use on initial page load. |
213
185
214
186
### `useTheme()`
215
187
@@ -231,7 +203,7 @@ Returns an object, with the following:
231
203
|`light`| String |`'light'`| Color value used for light theme. |
232
204
|`theme`| String |`'dark'`. | Color value used for dark theme. |
233
205
234
-
> **NOTE**: The `getColors()` function can be used in both, the client components and server components.
206
+
> **NOTE**: The `getColors()` function can be used in both, client components and server components.
235
207
236
208
For server components you can import `getColors()` like so:
237
209
@@ -296,10 +268,19 @@ To fix this, you can add the folder where your CSS or SASS file is located. For
296
268
// ...
297
269
```
298
270
271
+
#### `Warning: Extra attributes from the server: class,style` in Console
272
+
273
+
This warning _only_ shows on dev build and _not_ in the production build. This happens because the injected script adds _additional_`class` and `style` attributes to the `html` element which _do not_ originally exist on the server-side generated page, leading to a mismatch in the server-side and client-side rendered page.
0 commit comments