🎉
【Next.js】Next.js & Contentful BlogApp 【17tailwind darkmode】
【17tailwind darkmode】
YouTube:https://youtu.be/U6ujzixl-rc
今回からtailwind cssのdarkモードの設定を何回かに分けて解説します。
今回は、darkモードの初期設定とスタイリングを実装します。
まずはtailwindのコンフィグファイルの末尾に
darkModeの設定を追加します。
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {},
},
plugins: [],
darkMode: 'class',
}
そして、darkモードの対象となる一番上の親要素に「dark」のクラスを追加して、
各要素のスタイリングには「dark:from-purple-800」のように
先頭に「dark:」を設定します。
components/Layout.js
import Head from 'next/head'
import Navbar from './Navbar'
const Layout = ({ children, title = 'My Blog App' }) => {
return (
<div className={`dark`}>
<Head>
<title>{title}</title>
</Head>
<div className="w-full min-h-screen bg-gradient-to-r from-yellow-500 to-red-500 dark:from-purple-800 dark:to-pink-600">
<Navbar />
<main>{children}</main>
<footer className="py-3 text-center dark:text-white">
<span>© My Blog App</span>
</footer>
</div>
</div>
)
}
export default Layout
darkモードにすると、テキストの黒字が見えにくくなりますので、
darkモードの際にはテキストの色が白になるように設定します。
components/Heor.js
import Image from 'next/image'
const Hero = () => {
return (
<div className="w-full">
<div className="max-w-7xl flex flex-wrap justify-around items-center mx-auto py-6 px-3 gap-3">
<div className="dark:text-white">
<h1 className="font-bold text-8xl pb-5 mb-1">My Blog App</h1>
<p className="font-bold text-5xl mb-4">Next.js & Contentful</p>
<p className="font-bold text-2xl mb-2">Web Frontend & Backend</p>
</div>
<div>
<Image
src="/images/img_hero.png"
alt="main_visual"
width={600}
height={600}
/>
</div>
</div>
</div>
)
}
export default Hero
pages/posts/[slug].js
import Image from 'next/image'
import Layout from '../../components/Layout'
import { client } from '../../utils/contentfulClient'
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'
import { options } from '../../lib/richTextOptions'
export const getStaticPaths = async () => {
const res = await client.getEntries({
content_type: 'myPosts',
})
const paths = res.items.map((item) => {
return {
params: { slug: item.fields.slug },
}
})
return {
paths,
fallback: 'blocking',
}
}
export const getStaticProps = async ({ params }) => {
const { items } = await client.getEntries({
content_type: 'myPosts',
'fields.slug': params.slug,
})
if (!items.length) {
return {
notFound: true,
}
}
return {
props: { item: items[0] },
revalidate: 10,
}
}
const PostDetailsPage = ({ item }) => {
return (
<Layout title={item.fields.slug}>
<div className="w-full">
<div className="max-w-6xl flex flex-wrap justify-between items-center mx-auto py-6 px-5 gap-3">
<div className="dark:text-white">
<h1 className="font-bold text-3xl sm:text-4xl md:text-4xl lg:text-5xl py-3 mb-1">
{item.fields.title}
</h1>
<p className="font-bold text-2xl mb-2">
{item.sys.createdAt.substring(0, 10)}
</p>
</div>
<div>
<Image
src={`https:${item.fields.image.fields.file.url}`}
alt={item.fields.image.fields.description}
width={500}
height={500}
className="rounded"
/>
</div>
</div>
</div>
<div className="max-w-6xl mx-auto p-5 dark:text-white">
{documentToReactComponents(item.fields.content, options)}
</div>
</Layout>
)
}
export default PostDetailsPage
Discussion