DEV Community

Ferry Ananda Febian
Ferry Ananda Febian

Posted on

Cara Buat Dark Mode di Next.js 13 dengan Tailwind CSS

Dark mode adalah salah satu fitur yang sering kita temui di website, fungsi nya untuk memberikan pengguna kenyamanan membaca dan pengalaman yang unik.

Di artikel ini saya akan sharing bagaimana cara membuat dark mode di Next.js dengan Tailwind CSS.

Disini saya anggap pembaca semua sudah tau ya cara membuat project dengan Next.js dan sudah menginstall Tailwind CSS, jika belum, teman-teman dev bisa coba membuat project dengan panduan Next.js Getting Started

Aktifkan Dark Mode di Tailwind

Langkah pertama adalah mengaktifkan dark mode di Tailwind pada file **tailwind.config.js**, tambahkan baris kode berikut ini:

darkMode: 'class',
Enter fullscreen mode Exit fullscreen mode

Sehingga kode terlihat seperti berikut:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx}",
    "./src/components/**/*.{js,ts,jsx,tsx}",
    "./src/app/**/*.{js,ts,jsx,tsx}",
  ],
  darkMode: "class",
  theme: {
    extend: {
      backgroundImage: {
        "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
        "gradient-conic":
          "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
      },
    },
  },
  plugins: [],
};
Enter fullscreen mode Exit fullscreen mode

Dengan cara ini, kita dapat mengubah nilai class dengan mudah. Misal awalnya kita menerapkan background color defaultnya adalah “bg-zinc-50” dan class untuk darkMode adalah “bg-zinc-500”, maka kode akan kita tulis seperti berikut ini:

className="bg-zinc-50 dark:bg-zinc-900"
Enter fullscreen mode Exit fullscreen mode

Menulis Kode Dark Mode di Pages

Sebagai contoh di project Next.js, kita akan mencoba menuliskan kode DarkMode di src/app/page.tsx, maka ini contoh menulis kode class:

export default function Home() {
  return (
    <main className="bg-zinc-50 dark:bg-zinc-900 flex min-h-screen items-center justify-center">
      <div className="max-w-xs mx-auto">
        <h1 className="text-lg text-center text-zinc-900 dark:text-zinc-100">
          Contoh Dark Mode
        </h1>

        <p className="text-sm text-center text-zinc-700 dark:text-zinc-100">
          This is an example of how to implement dark mode in a Next.js app.
        </p>
      </div>
    </main>
  );
}
Enter fullscreen mode Exit fullscreen mode

Modifikasi layout

Pada project Next.js 13, file layout berada di src/app/layout.tsx, di file ini kita menambahkan properti dark di dalam className, seperti berikut ini:

import './globals.css'

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" className="dark">
      <body>{children}</body>
    </html>
  )
}
Enter fullscreen mode Exit fullscreen mode

Membuat Komponen Toggle

Komponen toggle ini kita gunakan sebagai button untuk mengalihkan mode dark ke light atau sebaliknya.

Komponen toggle bisa kita buat di “src/components” misal dengan nama ToggleTheme.tsx

Berikut kode di dalam komponen ToggleTheme.tsx

export default function ToggleTheme() {
  return (
    <button
      type="button"
      aria-label="Toggle dark mode"
      className="rounded-sm bg-zinc-900 px-2 py-1.5 dark:bg-zinc-100"
    >
      <span className="inline-block text-sm text-zinc-100 dark:hidden">
        Tema Dark Dong
      </span>
      <span className="hidden text-sm text-zinc-800 dark:inline-block">
        Tema Light Dong
      </span>
    </button>
  )
}
Enter fullscreen mode Exit fullscreen mode

Implementasi Cookies

Sebelum komponen Toggle dapat digunakan, kita coba implementasi cookies untuk mendapatkan preferensi tema yang sedang digunakan pengguna, jika pengguna menggunakan tema dark atau gelap, maka website kita otomatis menggunakan tema dark, begitu pula sebaliknya.

Untuk implementasi Cookies di Next.js, kita bisa menggunakan library yang bernama cookies-next. Berikut ini cara install nya:

npm install --save cookies-next
Enter fullscreen mode Exit fullscreen mode

Setelah selesai install library cookies-next, kita bisa membuat file di dalam src/utils dengan nama colorScheme.ts

import { getCookie, setCookie } from 'cookies-next'

export const getCurrentScheme = async () => {
  // The `getCookie` function is not available on the server, imagine that
  // we have to access the scheme while Next.js is rendering the `<RootLayout />`
  // component (this happens server side). We can use the `cookies` function
  // from the `next/headers` package to access the cookies from the request headers.
  if (typeof window === 'undefined') {
    return import('next/headers').then(({ cookies }) => {
      return cookies().has('scheme') ? cookies().get('scheme')?.value : 'light'
    })
  }

  return getCookie('scheme', { path: '/' })
}

export const toggleScheme = async () => {
  const scheme = await getCurrentScheme()

  const newScheme = scheme === 'dark' ? 'light' : 'dark'

  setCookie('scheme', newScheme, {
    path: '/',
  })

  return newScheme
}
Enter fullscreen mode Exit fullscreen mode

Kode diatas berfungsi untuk mengelola skema tampilan (dark mode atau light mode) pada aplikasi Next.js dengan menggunakan cookie untuk menyimpan status skema yang dipilih oleh pengguna.

Implementasi colorScheme.ts di komponen ToggleTheme.tsx

Setelah itu, kita coba import komponen colorScheme.ts kedalam komponen ToggleTheme.tsx

import { toggleScheme } from '@/utils/colorScheme';
Enter fullscreen mode Exit fullscreen mode

tambahkan function baru

const toggle = async () => {
await toggleScheme();
};
Enter fullscreen mode Exit fullscreen mode

lalu pada tag button, tambahkan properti onClick dan isi value dengan nama function diatas

onClick={toggle}
Enter fullscreen mode Exit fullscreen mode

dan jangan lupa tambahkan kode use client pada bagian atas komponen ToggleTheme.tsx yang menandakan file tersebut dieksekusi di sisi client. Disini juga kita gunakan useRouter untuk memperbaharui tampilan halaman.

'use client'
Enter fullscreen mode Exit fullscreen mode

kode sepenuhnya sebagai berikut:

'use client'

import { toggleScheme } from '@/utils/colorScheme'
import { useRouter } from 'next/navigation'

export default function ColorSchemeToggleButton() {
  const router = useRouter()

  const toggle = async () => {
    await toggleScheme()
    router.refresh()
  }

  return (
    <button
      type="button"
      aria-label="Toggle dark mode"
      className="rounded-sm bg-zinc-900 px-2 py-1.5 dark:bg-zinc-100"
      onClick={toggle}
    >
      <span className="inline-block text-sm text-zinc-100 dark:hidden">
        Switch to Dark
      </span>
      <span className="hidden text-sm text-zinc-800 dark:inline-block">
        Switch to Light
      </span>
    </button>
  )
}
Enter fullscreen mode Exit fullscreen mode

Modifikasi File Layout

Kembali lagi ke file layout.tsx, kita perlu mengimport komponen colorScheme yang dibuat pada folder utils dan membuat konstanta baru untuk menyimpan hasil dari komponen colorScheme.

Kode yang diterapkan sebagai berikut:

import './globals.css'
import { getCurrentScheme } from '@/utils/colorScheme'

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  const scheme = await getCurrentScheme()

  return (
    <html lang="en" className={scheme === 'dark' ? 'dark' : ''}>
      <body>{children}</body>
    </html>
  )
}
Enter fullscreen mode Exit fullscreen mode

Import ToggleTheme ke dalam pages

Setelah semua proses modifikasi dilakukan, kita coba import komponen ToggleTheme ke dalam pages.tsx

import ToggleTheme from '@/components/ToggleTheme '

export default function Home() {
  return (
    <main className="flex min-h-screen items-center justify-center bg-zinc-50 dark:bg-zinc-900">
      <div className="mx-auto max-w-xs">
        <h1 className="text-center text-lg text-zinc-900 dark:text-zinc-100">
          Contoh Dark Mode
        </h1>

        <p className="text-center text-sm text-zinc-700 dark:text-zinc-100">
          This is an example of how to implement dark mode in a Next.js app.
        </p>
      </div>
    </main>
  )
}
Enter fullscreen mode Exit fullscreen mode

Oke selesai, kita sudah berhasil implementasi Dark Mode di Next.js dengan Tailwind CSS.

Top comments (0)