Localstorage Problem
Unanswered
shadow posted this in #help-forum
shadowOP
what am i doing wrong?
ReferenceError: localStorage is not defined
at w (/var/task/.next/server/chunks/697.js:1:5820)
at nM (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47419)
at nM (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61663)
at nN (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64674)
at nB (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67657)
at nF (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:66824)
at nN (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64990)
at nM (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61233)
at nN (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64674)
at nI (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:46806)"use client"
import "../globals.css";
import * as React from "react";
import Sidebar from "@/components/Sidebar";
import { useState, useEffect } from "react";
export default function HomeLayout({ children }: { children: React.ReactNode }) {
const [sidebarOpen, setSidebarOpen] = useState(JSON.parse(localStorage.getItem('sidebarOpen') || 'true'));
useEffect(() => {
if (typeof window !== 'undefined') {
localStorage.setItem('sidebarOpen', JSON.stringify(sidebarOpen));
}
}, [sidebarOpen]);
return (
<div className="flex">
<Sidebar setVisible={setSidebarOpen} isVisible={sidebarOpen} />
<div className="md:hidden block w-full">
{(!sidebarOpen && children)}
</div>
<div className="md:block md:w-full hidden ">
{children}
</div>
</div>
);
}5 Replies
@shadow what am i doing wrong?
ReferenceError: localStorage is not defined
at w (/var/task/.next/server/chunks/697.js:1:5820)
at nM (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47419)
at nM (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61663)
at nN (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64674)
at nB (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67657)
at nF (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:66824)
at nN (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64990)
at nM (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61233)
at nN (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64674)
at nI (/var/task/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:46806)
js
"use client"
import "../globals.css";
import * as React from "react";
import Sidebar from "@/components/Sidebar";
import { useState, useEffect } from "react";
export default function HomeLayout({ children }: { children: React.ReactNode }) {
const [sidebarOpen, setSidebarOpen] = useState(JSON.parse(localStorage.getItem('sidebarOpen') || 'true'));
useEffect(() => {
if (typeof window !== 'undefined') {
localStorage.setItem('sidebarOpen', JSON.stringify(sidebarOpen));
}
}, [sidebarOpen]);
return (
<div className="flex">
<Sidebar setVisible={setSidebarOpen} isVisible={sidebarOpen} />
<div className="md:hidden block w-full">
{(!sidebarOpen && children)}
</div>
<div className="md:block md:w-full hidden ">
{children}
</div>
</div>
);
}
try an early return if window is undefined
import { useEffect, useState } from "React";
...
const [mounted, setMounted] = useState(false)
useEffect(() => {
setMounted(false)
},[])
if (!mounted) {
return null
}
...early return can be ok but sometimes you don't want everything to be non existent in prerendering, so it can be best to choose a default and then set the useState in useEffect and not directly in useState: https://nextjs-faq.com/browser-api-client-component
I do want to suggest not storing something so trivial into the local storage, both of the above comments are valid, but why are you storing sidebar state in local storage?
Im assuming side bar is a like navigation menu of sorts.
hi @shadow, I know I’m a bit late, but this might help someone encountering the same issue in the future.
Since Next.js pre-renders client components on the server, localStorage is not available on the server side. Therefore, you should remove localStorage from the initial useState call and move its usage inside a useEffect hook. This way, it will only execute once the component is rendered on the client.
From:
To:
Since Next.js pre-renders client components on the server, localStorage is not available on the server side. Therefore, you should remove localStorage from the initial useState call and move its usage inside a useEffect hook. This way, it will only execute once the component is rendered on the client.
From:
useState(JSON.parse(localStorage.getItem('sidebarOpen') || 'true'));To:
const [sidebarOpen, setSidebarOpen] = useState(true);
useEffect(() => {
const storedSidebarState = localStorage.getItem('sidebarOpen');
if (storedSidebarState) {
setSidebarOpen(JSON.parse(storedSidebarState));
}
}, []);