Documentation
Dark and Light mode with auto detection made easy with NuxtJS 🌗
Features
- Add
.${color}-mode
class to<html>
for easy CSS theming - Force a page to a specific color mode (perfect for incremental development)
- Works with any NuxtJS target (
static
orserver
) and rendering (universal
andspa
) - Auto detect the system color-mode
- Sync dark mode across tabs and windows 🔄
- Supports IE9+ 👴
Live demo
yarn add --dev @nuxtjs/color-mode
npm install --save-dev @nuxtjs/color-mode
Then, add @nuxtjs/color-mode
to the buildModules
section of your nuxt.config.js
{
buildModules: [
'@nuxtjs/color-mode'
]
}
Use the modules
property instead of buildModules
if:
- you are using
ssr: false
andnuxt start
, see #25 - you are using
nuxt < 2.9.0
You are ready to start theming your CSS with .dark-mode
and .light-mode
classes ✨
TypeScript
Add the types to your "types" array in tsconfig.json
{
"compilerOptions": {
"types": [
"@nuxt/types",
"@nuxtjs/color-mode"
]
}
}
Usage
It injects $colorMode
helper with:
preference
: Actual color-mode selected (can be'system'
), update it to change the user preferred color modevalue
: Useful to know what color mode has been detected when$colorMode === 'system'
, you should not update itunknown
: Useful to know if during SSR or Generate, we need to render a placeholderforced
: Useful to know if the current color mode is forced by the current page (useful to hide the color picker)
<template>
<div>
<h1>Color mode: {{ $colorMode.value }}</h1>
<select v-model="$colorMode.preference">
<option value="system">System</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="sepia">Sepia</option>
</select>
</div>
</template>
<style>
body {
background-color: #fff;
color: rgba(0,0,0,0.8);
}
.dark-mode body {
background-color: #091a28;
color: #ebf4f1;
}
.sepia-mode body {
background-color: #f1e7d0;
color: #433422;
}
</style>
Force a color mode
You can force the color mode at the page level (only parent) by setting the colorMode
property:
<template>
<h1>This page is forced with light mode</h1>
</template>
<script>
export default {
colorMode: 'light',
}
</script>
This feature is perfect for implementing dark mode to a website incrementally by setting the not-ready pages to colorMode: 'light'
.
We recommend to hide or disable the color mode picker on the page since it won't be able to change the current page color mode, using $colorMode.forced
value.
Example
You can see a more advanced example in the example/ directory or play online with the CodeSandBox below:
Configuration
You can configure the module by providing the colorMode
property in your nuxt.config.js
, here are the default options:
colorMode: {
preference: 'system', // default value of $colorMode.preference
fallback: 'light', // fallback value if not system preference found
hid: 'nuxt-color-mode-script',
globalName: '__NUXT_COLOR_MODE__',
componentName: 'ColorScheme',
classPrefix: '',
classSuffix: '-mode',
storageKey: 'nuxt-color-mode'
}
Notes:
'system'
is a special value, it will automatically detect the color mode based on the system preferences (see prefers-color-mode spec). The value injected will be either'light'
or'dark'
. Ifno-preference
is detected or the browser does not handle color-mode, it will set thefallback
value.
Caveats
When $colorMode.preference
is set to 'system'
, using $colorMode
in your Vue template will lead to a flash. This is due to the fact that we cannot know the user preferences when pre-rendering the page since they are detected on client-side.
To avoid the flash, you have to guard any rendering path which depends on $colorMode
with $colorMode.unknown
to render a placeholder or use our <ColorScheme>
component.
Example:
<template>
<ColorScheme placeholder="..." tag="span">
Color mode: <b>{{ $colorMode.preference }}</b>
<span v-if="$colorMode.preference === 'system'">(<i>{{ $colorMode.value }}</i> mode detected)</span>
</ColorScheme>
</template>
Props:
placeholder
:String
tag
:String
, default:'span'
TailwindCSS
Tailwind v2
Tailwind v2 introduced dark mode, in order to work with @nuxtjs/color-mode
, you need to set darkMode: 'class'
in your tailwind.config.js
:
module.exports = {
darkMode: 'class'
}
Then in your nuxt.config.js
, set the classSuffix
option to an empty string:
export default {
colorMode: {
classSuffix: ''
}
}
Checkout the live example on CodeSandBox.
Tailwind Dark Mode Plugin
You can easily integrate this module with tailwindcss-dark-mode by just setting darkSelector: '.dark-mode'
, see changing the selector documentation.
// tailwind.config.js
module.exports = {
theme: {
darkSelector: '.dark-mode'
},
variants: {
backgroundColor: ["dark", "dark-hover", "dark-group-hover", "dark-even", "dark-odd", "hover", "responsive"],
borderColor: ["dark", "dark-focus", "dark-focus-within", "hover", "responsive"],
textColor: ["dark", "dark-hover", "dark-active", "hover", "responsive"]
},
plugins: [
require('tailwindcss-dark-mode')()
]
}
Checkout a live example on CodeSandBox as well as @nuxtjs/tailwindcss module.
Contributing
You can contribute to this module online with CodeSandBox:
Or locally:
- Clone this repository
- Install dependencies using
yarn install
ornpm install
- Start development server using
yarn dev
ornpm run dev
License
Copyright (c) NuxtJS Team