@nuxtjs/color-mode でダークモードを導入する方法

Nuxt で実行したアプリにダークモードを導入したのでまとめる。

はじめに

Nuxt で作成したアプリケーションにダークモードを導入する際に便利なモジュールが @nuxtjs/color-mode です。

Nuxt Color Mode
Dark and Light mode with auto detection made easy with Nuxt 🌗
Nuxt Color Mode favicon https://color-mode.nuxtjs.org/
Nuxt Color Mode

次のコマンドを実行し、アプリケーションに必要なモジュールを追加します。

npx nuxi module add color-mode

nuxt.config.ts に以下のような設定が追加されていることを確認します。

export default defineNuxtConfig({
  modules: [
    '@nuxtjs/color-mode',
  ]
})

テーマの切り替えを実装する

カラーのテーマを切り替えるためのボタンやセレクトボックスを用意します。

公式サイトにもコード例が載っています。

ライトテーマとダークテーマだけで良い場合は以下のようになります。

<template>
  <select v-model="$colorMode.preference">
    <option value="light">Light</option>
    <option value="dark">Dark</option>
  </select>
</template>

値を変更する場合に $colorMode の value ではなく、preference を変更する点に注意してください。

value を変更してもテーマの切り替えはできますが、preference の値が書きかわらないため、リロードしたりページ遷移すると変更前のテーマになってしまいます。

CSS 変数を定義する

今回は CSS で文字色や背景色を変えられるようにします。

main.css という CSS ファイルを用意します。

私は以下のような変数を定義しました。

下記を参考にご自身のアプリで使いたいテーマごとに色を設定してください。

html.light-mode{
  --primary-text-color: ライトモードで使用する文字色;
  --primary-bg-color: ライトモードでメインで使用する背景色;
  --secondary-bg-color: ライトモードでサブで使用する背景色;
  --primary-border-color: ライトモードで使用する枠線の色;
}

html.dark-mode {
  --primary-text-color: ダークモードで使用する文字色;
  --primary-bg-color: ダークモードでメインで使用する背景色;
  --secondary-bg-color: ダークモードでサブで使用する背景色;
  --primary-border-color: ダークモードで使用する枠線の色;
}

動作確認

ライトモードを使用している場合です。

本サイトをライトモードで表示したスクリーンショット

ダークモードを使用している場合です。

本サイトをダークモードで表示したスクリーンショット

Storybook を使用している場合のモック方法

Storybook で表示しようとすると @nuxtjs/color-mode の $colorMode が undefined となってしまい、エラーが表示されてしまいます。

そこで、下記のように $colorMode をモックすることで Storybook でも $colorMode を使ったコンポーネントを表示することができるようになります。

export default {
  render: () => ({
    components: { コンポーネント名 },
    setup() {
      const colorMode = {
        value: 'light',
        preference: 'light',
        unknown: false,
        forced: false,
      }
      const app = getCurrentInstance()?.appContext.app
      if (app) {
        app.config.globalProperties.$colorMode = colorMode
      }
      return {}
    },
    template: `
      <コンポーネント名 />
    `,
  }),
}

まとめ

@nuxtjs/color-mode を使用するとダークモードを簡単に導入することができました。

個人的にはダークモードにした場合の配色を考える方が大変でした。