Home > Mobile >  Dark Mode not working in Tailwind CSS V3 with Next.js & Typescript
Dark Mode not working in Tailwind CSS V3 with Next.js & Typescript

Time:12-16

I have been struggling to make dark mode work in my Next.js App. I am using Context For handling the change in the dark mode and trying using the getLayout feature to get that app-like experience for the App. Here is the code for different files in the directory.

For src/contexts/color-mode.tsx:

import { createContext, useContext, FC, useState } from "react";

interface IThemeContext {
  dark: boolean;
  toggleDark?: () => void;
}

const defaultState = {
  dark: false,
};

const ThemeContext = createContext<IThemeContext>(defaultState);

export const useTheme = () => useContext(ThemeContext);

const ThemeProvider: FC = ({ children }) => {
  const [dark, setDark] = useState(defaultState.dark);
  const toggleDark = () => {
    setDark(!dark);
  };
  return (
    <ThemeContext.Provider value={{ dark, toggleDark }}>
      {dark ? <div className="dark">{children}</div> : <div>{children}</div>}
    </ThemeContext.Provider>
  );
};

export default ThemeProvider;

For src/pages/index.tsx:

import { useTheme } from "contexts/color-mode";
import { NextPageWithLayout, Marketing } from "layouts";

const Page: NextPageWithLayout = () => {
  const { toggleDark } = useTheme();
  return (
    <div className="flex items-center justify-center flex-col">
      I hoped that this would render ahout now!
      <span className="text-red-600">Does this render!?</span>
      <button
        onClick={toggleDark}
        className="text-white bg-black rounded-md px-3 py-2 dark:text-black dark:bg-white"
      >
        Toggle Mode
      </button>
    </div>
  );
};

Page.getLayout = (page) => <Marketing>{page}</Marketing>;

export default Page;

Layout For the Home page in src/layouts/marketing.tsx:

import { Navbar } from "components";
import type { FC } from "react";

const Marketing: FC = ({ children }) => {
  return (
    <div className={"min-h-screen w-screen"}>
      <Navbar />
      <p>This is the marketing pages layout.</p>

      {children}
    </div>
  );
};

export default Marketing;

The Navbar does not contain anything except some boilerplate.

The code for _app is in src/pages/_app.tsx:

import { useEffect } from "react";
import ThemeProvider from "contexts/color-mode";
import { EnhancedApp } from "layouts";
import { noCopy } from "utils";
import "styles/tailwind.css";

const MyApp = ({ Component, pageProps }: EnhancedApp) => {
  useEffect(() => {
    noCopy();
  }, []);
  const getLayout = Component.getLayout ?? ((page) => page);
  return (
    <ThemeProvider>{getLayout(<Component {...pageProps} />)}</ThemeProvider>
  );
};

export default MyApp;

The No Copy function deals with the dom which does not use react features.

If you can help then that would be much appreciated. Thanks in advance.

Here is the tailwind.config.js:

module.exports = {
  content: ["./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

CodePudding user response:

How I did it recently was:

Add darkMode: 'class', to your config file.

Then you can manually append the className "dark" to the body tag, when you want to enable dark mode, then all the dark:tailwind-class stuff will enable. You could also do it per section basis. here are the docs https://www.tailwindcss.com/docs/dark-mode

  • Related