🥑
Next.js, daisyUIでダークモード付きブログを爆速で作る
注意点
- 使用エディタ: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(見た目の調整)書くためのやつ。
楽なので導入します。
yarn add -D tailwindcss postcss autoprefixer
yarn tailwindcss init -p
daisyUI の導入
UIのパーツがたくさん入ってるやつでめちゃ便利なので導入します。
Tailwind CSSが必須です。
ダークモードの実装等も簡単になるのでオススメ。
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にて紹介されていたものを引用しています。
Discussion