初めに
最近、Next.jsにTailwind CSSで作成した個人ブログにダークモード機能を追加したので、その備忘録として。
Tailwindのダークモードを有効化する
TailwindのV-2からダークモードが組み込まれており、ダークモード時に指定の色に切り替えてくれるようになりました。
ダークモードを有効化するのは簡単で、tailwind.config.jsのdarkModeにclassかmediaを指定するだけです。mediaを指定した場合は、OSの設定に基づいて、自動でdarkモードに切り替えてくれますが、今回はユーザーがページ上でON/OFFの切り替えが出来るようにしたいので、classを指定して、ダークモードを有効化させます。
詳細はTailwindのドキュメントに記載されてます。
module.exports = {
  purge: [],
  darkMode: 'class', //ダークモードを有効化する
  theme: {
    extend: {
      colors: {
        darkgrey: '#222831', //darkModeで使用したい色を拡張定義
      },
    },
  },
  variants: {
    extend: {
},
  },
  plugins: [],
};
next-themesをインストールする
次にボタンを押下した際に、htmlタグのclassに対してdarkをアクティブ/非アクティブにするための実装が必要になります。
<html class="dark">
Tailwindのダークモードは、htmlタグのclassにdarkが付与されてる場合、以下のような記述で、ダークモード時の色を指定する事が出来ます。
<div className="dark:bg-darkgrey dark:text-white">
ドキュメントには現在のモードをlocalStorageに保存する方法が紹介されていますが、ここでは、next-themesというライブラリを使って実装を進めます。
$ npm install next-themes
# or
$ yarn add next-themes
ライブラリをインストールしたら、_app.jsにThemeProviderをimportします。
attributeにはclassを指定しましょう。(※Tailwindのダークモードを使用するには、この記述が必要です)
import '../../styles/globals.css';
import '../../styles/common.css';
import { AppProps } from 'next/app';
import { ThemeProvider } from 'next-themes';
function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ThemeProvider attribute="class">
      <Component {...pageProps} />
    </ThemeProvider>
  );
}
export default MyApp;
ダークモードを切り替えるボタンを作成する
切り替えるボタンは以下のようにしました。
useTheme()フックを利用して、テーマの切り替えを制御します。
import { useTheme } from 'next-themes';
const { theme, setTheme } = useTheme();
// レンダー後かを判定
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
<button
  aria-label="DarkModeToggle"
  type="button"
  className="p-3 h-12 w-12 order-2 md:order-3 absolute left-2/4 transform -translate-x-2/4 md:relative md:left-0"
  onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
>
  {mounted && (
    <>
      {theme === 'dark' ? (
        <Moon height={'25'} width={'25'} />
      ) : (
        <Sun height={'25'} width={'25'} />
      )}
    </>
  )}
</button>
後は、Tailwindのいつもの書き方でダークモード時の色を指定してあげるだけです。
<div className="relative mb-10 dark:bg-darkgrey">
...
</div>
以上、これでお手軽にダークモードを実装することが出来ます。