🥑

Next.js, daisyUIでダークモード付きブログを爆速で作る

2024/01/15に公開

注意点

  • 使用エディタ:Rider
  • 筆者:web入門者

環境

  • next: latest
  • react: 18.2.0
  • daisyui: 4.6.0
  • tailwindcss: 3.4.1

環境構築

yarnのインストール

以下をterminal等にて入力。

npm i --global yarn

ブログテンプレート作成

以下を入力。YOUR_PROJECT_NAMEには任意のプロジェクト名を入れてください。

yarn create next-app --example blog-starter YOUR_PROJECT_NAME

ローカルでの実行

プロジェクトのファイルに移動してからローカルで実行。

cd YOUR_PROJECT_NAME
yarn dev

http://localhost:3000/ にてページが出ることを確認します。
出たらローカルでの実行はクリア。

Tailwind CSS の導入

楽にcss(見た目の調整)書くためのやつ。
楽なので導入します。

https://tailwindcss.com/

yarn add -D tailwindcss postcss autoprefixer
yarn tailwindcss init -p

daisyUI の導入

UIのパーツがたくさん入ってるやつでめちゃ便利なので導入します。
Tailwind CSSが必須です。
ダークモードの実装等も簡単になるのでオススメ。

https://daisyui.com

yarn add -D daisyui@latest

インストール後、tailwind.config.jsを以下のように書き換えます。

tailwind.config.js
module.exports = {
    content: ["./components/**/*.tsx", "./pages/**/*.tsx"],
    plugins: [require("daisyui")],
    daisyui: {
        themes: ["light", "dark"],
    }
};

これだけで、自分のPCのシステム設定に合わせたテーマに変わります!

記事の投稿

next.jsのblog-starterでは、./posts下のmarkdownファイルが自動的にhtmlに変換される仕様になっています。

デフォルトで存在するフロントマッター(markdownのメタ情報を管理するやつ)は以下。

わからなかったらblog-starterに入っているhello-world.mdを参考にして書けばOKです。

---
title: "記事のタイトル"
excerpt: "記事の要約(タイトルの下に表示される部分)"
coverImage: "記事のサムネイル(YOUR_PROJECT_NAME/public下の画像を参照できる)"
date: "執筆した日時"
author:
  name: "書いた人"
  picture: "書いた人のアイコン"
ogImage:
  url: "OG(他サービスでの埋め込み時)にて表示する画像"
---

その他

カラーモードの変更

カラーモードを変更する機能を作りたい場合。

/componentsにて以下のようなtsxファイルを追加します。

theme-changer.tsx
import {useEffect, useState} from "react";

const ThemeChanger = () => {
    const [theme, setTheme] = useState("light")

    const handleToggle = (e) => {
        if (e.target.checked) {
            setTheme("dark");
        } else {
            setTheme("light");
        }
    }

    useEffect(() => {
        const localTheme = localStorage.getItem("theme");
        if (localTheme) {
            setTheme(localTheme);
        }
    }, []);
    
    useEffect(() => {
        localStorage.setItem("theme", theme);
        document.documentElement.setAttribute("data-theme", theme);
    }, [theme]);
    
    return (
        <h4 className="text-center md:text-left text-lg mt-5 md:pl-8">
            <label className="swap swap-rotate">

                {/* this hidden checkbox controls the state */}
                <input type="checkbox" onChange={handleToggle}/>

                {/* sun icon */}
                <svg className="swap-on fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg"
                     viewBox="0 0 24 24">
                    <path
                        d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"/>
                </svg>

                {/* moon icon */}
                <svg className="swap-off fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg"
                     viewBox="0 0 24 24">
                    <path
                        d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"/>
                </svg>

            </label>
        </h4>
    )
};

export default ThemeChanger;

これを任意の部分に追加。

例えばcomponents/intro.tsxに追加してみます。

intro.tsx
 import {CMS_NAME} from "../lib/constants";
 import ThemeChanger from "./theme-changer";

 const Intro = () => {
     return (
         <section className="flex-col md:flex-row flex items-center md:justify-between mt-16 mb-16 md:mb-12">
             <h1 className="text-5xl md:text-8xl font-bold tracking-tighter leading-tight md:pr-8">
                 Blog.
             </h1>
             <h4 className="text-center md:text-left text-lg mt-5 md:pl-8">
                 A statically generated blog example using{" "}
                 <a
                     href="https://nextjs.org/"
                     className="underline hover:text-blue-600 duration-200 transition-colors"
                 >
                     Next.js
                 </a>{" "}
                 and {CMS_NAME}.
             </h4>
+            <ThemeChanger/>
         </section>
     );
 };
 
 export default Intro;

そうすれば、右上にライト・ダークモード切り替えのボタンが追加されます(太陽・月マークのやつ)!

ちなみにこれはdaisyUIにて紹介されていたものを引用しています。

https://daisyui.com/components/swap/#swap-icons-with-rotate-effect

Discussion