using local storage causes flicking which is a paradox
Unanswered
Gouty oak gall posted this in #help-forum
Gouty oak gallOP
Is there a way to use local storage in server side instead of client side?
I need to use local storage for dark mode. I'm using nextjs14, tailwindcss, and typescript. To use local storage, I need to use useEffect and for that i need to make that file client. And because of that there is a flicking affect which causes to see light mode for a second even tho user's theme is dark. I don't want to solve it with external packages cause I use local storage in my other projects for different reasons and if I can solve for this one, i can solve for all of them.
This is for themetoggle:
and this is for another project's:
I need to use local storage for dark mode. I'm using nextjs14, tailwindcss, and typescript. To use local storage, I need to use useEffect and for that i need to make that file client. And because of that there is a flicking affect which causes to see light mode for a second even tho user's theme is dark. I don't want to solve it with external packages cause I use local storage in my other projects for different reasons and if I can solve for this one, i can solve for all of them.
This is for themetoggle:
"use client"
import {useEffect, useState } from "react";
export default function ThemeToggle(){
const [darkMode, setDarkMode] = useState(false);
useEffect(()=>{
const theme = localStorage.getItem('theme');
if (theme === 'dark') {
setDarkMode(true);
}
},[]);
useEffect(()=>{
if(darkMode){
document.documentElement.classList.add("dark");
localStorage.setItem('theme', 'dark');
}else{
document.documentElement.classList.remove("dark");
localStorage.setItem('theme', 'light');
}
},[darkMode]);
return (
<button onClick={()=>setDarkMode(!darkMode)}>Lights</button>
)
}and this is for another project's:
'use client'
import { createContext, useContext } from "react";
import { useEffect, useState } from "react";
...
// Check local storage for date on component mount
useEffect(() => {
const storedDate = localStorage.getItem('date');
if (storedDate) {
setDate(storedDate);
}
}, []);
...
15 Replies
Is there a way to use local storage in server side instead of client side?No. Because it's the localstorage. The server itself don't know any states so it's not possible to have a localstorage serverside.
@Gouty oak gall that's a classic issues let me gather some sources
first, you can use cookies: they are similar to localStorage from the client point of view
but with the advantage that they are also sent to the server so they are a better fit for Next which relies heavily on server-side rendering
it's impossible to achive that with localStorage, which is strictly limited to client-side
You'd want to take alook at https://github.com/pacocoursey/next-themes
if you don't want to reuse the package, that's fine, but you'd still want to dig the architecture
I am not 100% it's up to date with RSCs though, it has to rely on a hackish supresshydrationwarning, but I haven't digged it recently so you'll want to double check
another rather radical solution is segmented rendering:
basically you store the theme in a cookie, and then use the same pattern as for i18n to handle the personalization, via a route parameter
For your other example with Dates, treat that as a separate issue, it's not related
theming is a case of personalization, you'll want it to work both in SSR and client-side rendering
while your date example is a case of client-only code in Next.js, I've also written on that topic: https://medium.com/@eric.burel/how-to-get-rid-of-window-is-not-defined-and-hydration-mismatch-errors-in-next-js-567cc51b4a17, it can only work after mounting client-side
Gouty oak gallOP
Thank you @Eric Burel I'll check everything you sent. I've to look up for how to use cookies