@nuxtjs/color-mode

repository·main·Indexed 22 days ago

https://github.com/nuxt-modules/color-mode

A Nuxt module for implementing dark and light modes with automatic system preference detection. It manages color preferences by applying configurable CSS classes (e.g., .dark or .light) to the <html> element and provides the useColorMode() composable and $colorMode global property for state management. Compatible with Nuxt 3+, it supports client-side and universal rendering, page-level mode forcing via definePageMeta, and integration with Tailwind CSS v3 and v4.

Tokens
4.4K
Snippets
20
Records
30
Agent score
76%

What's inside @nuxtjs/color-mode

  1. Nuxt Color Mode overview

    main
    Nuxt Color Mode is a module designed to make implementing dark and light modes easy in Nuxt applications. It automatically detects the user's system color preference and provides a mechanism to apply color themes via CSS classes.
  2. Key features of Nuxt Color Mode

    main

    Nuxt Color Mode provides the following capabilities:

    • CSS Theming: Automatically adds a .${color} class (e.g., .dark or .light) to the <html> element, allowing you to write theme-specific CSS easily.
    • Mode Forcing: Allows you to force a specific page into a specific color mode, which is useful for incremental development.
    • Rendering Support: Works seamlessly with both client-side and universal rendering.
    • System Auto-detection: Automatically detects the user's system color-mode preference using CSS media queries.
  3. Integrate with Tailwind CSS v4

    main

    By default, this module adds a class (e.g., .dark) to the <html> element. In Tailwind CSS v4, you must override the dark variant to use this class instead of the default prefers-color-scheme media query.

    To enable dark mode support, add the following to your CSS file:

    @import "tailwindcss";
    
    @custom-variant dark (&:where(.dark, .dark *));

    You can also create custom variants for other color modes (like sepia) using the same pattern:

    @custom-variant sepia (&:where(.sepia, .sepia *));

    Then use them in your templates:

    <div class="bg-white dark:bg-gray-900 sepia:bg-amber-50">
      <h1 class="text-gray-900 dark:text-white sepia:text-amber-900">
        Hello world
      </h1>
    </div>
    @import "tailwindcss";
    
    @custom-variant dark (&:where(.dark, .dark *));
    @custom-variant sepia (&:where(.sepia, .sepia *));
  4. Configure the Color Mode module

    main

    You can configure the @nuxtjs/color-mode module by providing the colorMode property in your nuxt.config.ts.

    Default configuration example:

    export default defineNuxtConfig({
      modules: ['@nuxtjs/color-mode'],
      colorMode: {
        preference: 'system', // default value of $colorMode.preference
        fallback: 'light', // fallback value if not system preference found
        globalName: '__NUXT_COLOR_MODE__',
        componentName: 'ColorScheme',
        classPrefix: '',
        classSuffix: '',
        storage: 'localStorage', // or 'sessionStorage' or 'cookie'
        storageKey: 'nuxt-color-mode',
        cookieAttrs: { maxAge: 31536000, path: '/' }
      }
    })
  5. Migrate from Nuxt 2 to Nuxt 3+ (v3 migration)

    main

    When moving from Nuxt 2 to Nuxt 3+, the primary change is how color mode is configured at the page level. Instead of using the component option, use definePageMeta within <script setup>.

    <script setup>
    definePageMeta({
      colorMode: 'light',
    })
    </script>
    
    <template>
      <h1>This page is forced with light mode</h1>
    </template>
  6. Override cookieAttrs at runtime

    main

    The cookieAttrs option is exposed through Nuxt's public runtime config, allowing you to change cookie attributes (like domain) per deployment without rebuilding.

    Values provided via runtimeConfig or environment variables are deep-merged with your existing cookieAttrs configuration.

    Important: Because storage is fixed at build time, you must set storage: 'cookie' in your nuxt.config.ts for runtime cookie overrides to work.

    // Option 1: Using runtimeConfig in nuxt.config.ts
    export default defineNuxtConfig({
      colorMode: {
        storage: 'cookie', // Must be set at build time
      },
      runtimeConfig: {
        public: {
          colorMode: {
            cookieAttrs: { domain: 'example.com' }, // Merged with defaults
          },
        },
      },
    })
  7. Override cookieAttrs using environment variables

    main

    You can override cookieAttrs using NUXT_PUBLIC_* environment variables.

    Note: Environment variables can only override keys that already exist on the object. You must first declare the key (even with an empty value) in your nuxt.config.ts or runtimeConfig so the module knows it exists.

    // nuxt.config.ts
    colorMode: {
      storage: 'cookie',
      cookieAttrs: { domain: '' }, // Declare domain so it can be overridden
    }
    NUXT_PUBLIC_COLOR_MODE_COOKIE_ATTRS_DOMAIN=example.com node .output/server/index.mjs
  8. Force a specific color mode on a page

    main

    You can override the global color mode for a specific page by using the definePageMeta macro. This is useful for incrementally implementing dark mode by forcing specific pages to remain in light mode.

    When a mode is forced, the color mode picker will not be able to change the current page's mode. You can check if the current mode is being forced by inspecting the $colorMode.forced value. It is recommended to hide or disable your color mode switcher on pages where a mode is forced to avoid user confusion.

    <template>
      <h1>This page is forced with light mode</h1>
    </template>
    
    <script setup>
    definePageMeta({
      colorMode: 'light',
    })
    </script>
  9. Integrate with Tailwind CSS v3

    main

    To use the color mode classes with Tailwind CSS v3, you must configure the darkMode option in your tailwind.config.js.

    Set darkMode to 'selector' (for Tailwind v3.4.1+) or 'class'.

    Note: If you are using @nuxtjs/tailwindcss v6 with Tailwind CSS v3, this configuration is handled automatically.

    export default {
      darkMode: 'selector',
    }