pacocoursey / next-themes

Perfect Next.js dark mode in 2 lines of code. Support System preference and any other theme with no flashing

Home Page:https://next-themes-example.vercel.app/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

background color initial issue

ChrAlpha opened this issue · comments

I wanna use Disqus on my Next.js website. Disqus could get color scheme correctly. However, the background color of Disqus thread remains white even I load Disqus in dark mode.

image image

Several relevant details that maybe useful:

  1. I use next-themes and TailwindCSS to feat darkmode. If I only use TailwindCSS with darkMode: 'media', both color scheme and background color of Disqus are correct.
  2. Disqus's use background: 0 0 which includes background-color: initial. Considering this and 1., I guess it is next-themes that changes the initial behaviour of background-color.
  3. When I load Disqus in light mode and manually toggle to dark mode, the background color of Disqus is correct.
  4. Nothing changed after I add bg-white dark:bg-black to <html>, <body> or any other parent elements of Disqus

You can check this demo, never mind the Chinese content, just scroll to the bottom and click the button to load Disqus.

Though I'm a new learner of front-end, I'm willing to make an effort on it. Just tell me anything I could do and I'll try my best.

Step further, I dig out sth intereting.

When I try using Context to feat next-themes manually, both color scheme and background color of Disqus are correct.

You can check this demo.

my code goes here
'use client'

import { useState, useEffect, useContext, createContext } from 'react'

const ThemeContext = createContext()

export const useTheme = () => {
  return useContext(ThemeContext)
}

export const ThemeProviders = ({ children }) => {
  const [theme, setTheme] = useState('system')
  const [colorScheme, setColorScheme] = useState('light')

  const toggleTheme = (color) => {
    if (color !== 'system' && color !== 'light' && color !== 'dark') {
      color = 'system'
    }
    setTheme(color)
    typeof window !== 'undefined' && localStorage.setItem('user-color-scheme', color)
  }

  useEffect(() => {
    let localTheme = localStorage.getItem('user-color-scheme')
    if (localTheme && localTheme !== 'system') {
      setTheme(localTheme)
    }

    const handleColorSchemeChange = (event) => {
      if (!event) {
        event = window.matchMedia("(prefers-color-scheme: dark)")
      }
      if (event.matches) {
        setColorScheme("dark")
      } else {
        setColorScheme("light")
      }
    }

    handleColorSchemeChange()
    window.matchMedia("(prefers-color-scheme: dark)").addListener(handleColorSchemeChange)

    return () => {
      window.matchMedia("(prefers-color-scheme: dark)").removeListener(handleColorSchemeChange)
    }
  }, [])


  useEffect(() => {
    document.documentElement.classList.add(theme === 'system' ? colorScheme : theme)
    return () => {
      document.documentElement.classList.remove(theme === 'system' ? colorScheme : theme)
    }
  }, [theme, colorScheme])

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      <script dangerouslySetInnerHTML={{__html: `document.documentElement.classList.add((typeof localStorage.getItem('user-color-scheme') === 'undefined' || localStorage.getItem('user-color-scheme') === 'system') ? (window.matchMedia("(prefers-color-scheme: dark)").matches ? 'dark' : 'light') : (localStorage.getItem('user-color-scheme') === 'dark' ? 'dark' : 'light'))`}} />
      {children}
    </ThemeContext.Provider>
  )
}

export const ToggleTheme = ({ responsive }) => {
  const [mounted, setMounted] = useState(false)
  const { theme, toggleTheme } = useTheme()

  useEffect(() => {
    setMounted(true)
  }, [])

  if (!mounted) {
    return null
  }

  return (
...

Not a issue related to the library but rather faulty usage.