use-dark-mode
use-dark-mode copied to clipboard
Is there any way to implement useDarkMode config static or server-side? (NextJS)
I'm trying to implement the configuration for useDarkMode hook, it works when NextJS uses CSR, but has an error when renders in server-side.
Any way to implement that configuration in SSG or SSR?
Also i want to use the element for <html>
anchor tag, because of using Tailwind CSS, so it's crucial for me to implement element
attribute.
My code:
function MyApp({ Component, pageProps }: AppProps) {
useEffect(() => {
// @ts-ignore
const darkMode = useDarkMode(false, {
classNameDark: "dark",
classNameLight: "light",
element: document.getElementsByTagName("html")[0]
});
}, [])
return (
<Fragment>
<Head>
<title>Oficjalna strona Nostalgawki</title>
<meta name="viewport" content="initial-scale=1, width=device-width"/>
</Head>
<div className={"main"}>
<AnimatePresence exitBeforeEnter>
<Navbar key={"navbar"}/>
<Component key={"component"} {...pageProps} />
<Footer key={"footer"}/>
</AnimatePresence>
</div>
</Fragment>
);
}
Great question, I'd be interested to see what the resolution here is. This is a great package.
El vie., 4 de diciembre de 2020 10:43 a. m., TenDan < [email protected]> escribió:
I'm trying to implement the configuration for useDarkMode hook, it works when NextJS uses CSR, but has an error when renders in server-side. Any way to implement that configuration in SSG or SSR? Also i want to use the element for anchor tag, because of using Tailwind CSS, so it's crucial for me to implement element attribute.
My code:
function MyApp({ Component, pageProps }: AppProps) { useEffect(() => { // @ts-ignore const darkMode = useDarkMode(false, { classNameDark: "dark", classNameLight: "light", element: document.getElementsByTagName("html")[0] }); }, [])
return ( <Fragment> <Head>
Oficjalna strona Nostalgawki </Head> <div className={"main"}> <AnimatePresence exitBeforeEnter> <Navbar key={"navbar"}/> <Component key={"component"} {...pageProps} /> <Footer key={"footer"}/> </AnimatePresence> </Fragment> ); }— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/donavon/use-dark-mode/issues/64, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMV42QRFRTTBM7MIN6N22LTSTD7RRANCNFSM4UNTJMJA .
Also running into the same issue. What are your thoughts on this @donavon ?
@TenDan
useDarkMode
(or any hook for that matter) can NOT be used inside of a useEffect
hook. There's also no need.
As to using html
instead, you can always specify an onChange
handler and do the work yourself.
For example:
const { value } = useDarkMode(false, {
onChange: (state: boolean) => {
const htmlElement = document.documentElement;
if (state) {
htmlElement.classList.add('dark');
htmlElement.classList.remove('light');
} else {
htmlElement.classList.add('light');
htmlElement.classList.remove('dark');
}
}
});
Can you give a short example of this failing in SSR that I can clone and run locally?
Hey!
Since the localStorage
variable doesn't really exist during SSR, the hook might have some unintended behavior.
I managed to get it working well by using use-ssr
.
// ...other imports
import { useSSR } from "use-ssr"
// Prints whether to dark mode is on / off
const DarkThemeTruthy = () => {
// Get theme value
const { value } = useDarkMode(false, {
classNameDark: "dark",
classNameLight: "light",
storageKey: "dark-theme",
})
// Get rendering mode
const { isBrowser } = useSSR()
return <Fragment>{isBrowser && <div>{value}</div>}</Fragment>
}
I've tested this on a Gatsby site, using both React and Preact.
It works quite well but there is one caveat.
Since useSSR
is being used, the <div>
is Client Side Rendered.
Hope this helps!