DEV Community

loading...
Cover image for How I built the dark mode of tailwindcss.com (website + docs) in 10 minutes using Nightwind & Next.js

How I built the dark mode of tailwindcss.com (website + docs) in 10 minutes using Nightwind & Next.js

jj_ranalli
Full stack maker. Creator of Nightwind (nightwindcss.com)
・2 min read

Nightwind is a plugin for Tailwindcss that automatically generates the dark mode of any Tailwind website, while also giving full customisation options.

GitHub logo jjranalli / nightwind

An automatic, customisable, overridable Tailwind dark mode plugin

From now on, I'll be creating the dark mode of well-known Tailwind websites to explore how Nightwind behaves in different cases. Especially, the effectiveness of its automatic dark mode.

What Nightwind does is essentially invert the color classes used throughout a website (for example, a bg-red-300 turns into bg-red-600). Thanks to the curated Tailwind color palette, this usually results in a good-looking, coherent dark mode.

I picked tailwindcss.com as the first one, as I felt it would've been the most challenging given the complexity and extensive use of color classes throughout the websites.

Tailwindcss.com homepage dark-mode comparison

Tailwindcss.com documentation dark-mode comparison

You can check the dark version of the homepage and the whole documentation here -> https://night-tailwindcss.vercel.app (press the Nightwind toggle in the navbar)


How I did it

1. Set up Nightwind in next.js, using 'next-themes'

I use ThemeProvider to manage light and dark modes, setting the storageKey parameter to 'nightwind-mode' to make sure the chosen mode persists.

// _app.js
import { ThemeProvider } from "next-themes"

function MyApp({ Component, pageProps }) {
  return (
    <ThemeProvider
      attribute="class"
      storageKey="nightwind-mode"
      defaultTheme="system" // default "light"
    >
      <Component {...pageProps} />
    </ThemeProvider>
  )
}

export default MyApp
Enter fullscreen mode Exit fullscreen mode

In _document.js I simply add the "nightwind" class to the Html element, which is used by Nightwind to manage transitions between modes.

// _document.js
import Document, { Html, Head, Main, NextScript } from "next/document"

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html className="nightwind">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument
Enter fullscreen mode Exit fullscreen mode

2. Set up a toggle

import { useTheme } from "next-themes"

export default function Toggle() {
  const { theme, setTheme } = useTheme()

  const toggle = () => {
    if (!document.documentElement.classList.contains("dark")) {
      setTheme("dark")
    } else {
      setTheme("light")
    }
  }

  return <button onClick={toggle}>Toggle</button>
}
Enter fullscreen mode Exit fullscreen mode

3. Add Nightwind into Tailwind.config.js

Finally, I specify what colorClasses and variants I want Nightwind to invert, as well as add the "typography: true" option to invert all colors used by the typography plugin (used in the tailwind documentation).

module.exports = {
  darkMode: "class",
  theme: {
     nightwind: {
       typography: true,
       colorClasses: ['gradient', 'ring', 'ring-offset', 'divide', 'placeholder'],
     },
  variants: {
    nightwind: ['group-hover', 'active', 'focus'],
  },
  plugins: [require("nightwind")],
}
Enter fullscreen mode Exit fullscreen mode

Note: There are also some minor modifications that were made to make everything work seamlessly. You can explore the full commit here


To learn more about Nightwind, I suggest you visit:

Thanks for reading! And if you have any suggestion about what other Tailwind website I should create the dark mode for, please let me know! :)

Discussion (1)

Collapse
cryptus_neoxys profile image
Dev Sharma

This is so good
Perfectly fits with the dev patterns of Nextjs.