Local Storage vs SSR

Don't trust everything you import
Published on 2024/01/30

I wanted to add a simple "like" functionality to my thoughts here. I did this to explore the KV store offering from Vercel and to play a bit more with Next.js. Since I just wanted to know if someone already "niced" a thought, I decided to leverage local storage. Simple as that. So yeah you can clear your local storage and upvote to the moon or send a thought to negative values. Have fun!

As you can imagine there were plenty of ready-to-use useLocalStorage hooks so I grabbed the first one and used it as per documentation.

const [myVal, setMyVal] = useLocalStorage("name", "");

Pretty simple. But the styling of the Nice button depends on the value in local storage:

background: ${(props) => (props.myVal !== "" ? "red" : "transparent")};

But once you "Niced" a post, while the data was correct and I would know if you niced it before, the styling would show a transparent background. The thing I was missing is that Next.js does heavy SSR. Ah!

This means that the style rendered server side and the style rendered on the client were mismatching (which in turn makes hydration messy). As I open the console, Next.js is actually warning me about it. So I happily remove an overkill dependency and pulling out all the fluff, it boils down to:

const [myVal, setMyVal] = useState("");

useEffect(() => {
  const storedValue = localStorage.getItem("name");
  if (storedValue !== null) {
    setMyVal(JSON.parse(storedValue));
  }
}, []);

Tada! Now server rendered component and client rendered component match. On first mount I check the local storage to update the button style accordingly.

Thoughts

This was actually pretty trivial to solve but it surfaced a nuance of SSR. Anything that depends on a browser API won't work on the server so you can end up with mismatching rendered components like I did. This is particularly true if the initial state depends on it, as it happened here.

That said, for something so simple you don't need a dependency. Generally I prefer to keep my node_modules as tight as possible.

0
← Go Back