localStorage in static NextJS site: ReferenceError: localStorage is not defined

Viewed 5180

I'm trying to use localStorage on a NextJS static site but running into the localStorage is not defined error.

My code for the component where the error shows, is:

export default function Category() {

const [cart, setCart] = useState(
        localStorage.getItem("myCart") || ""
    );

 useEffect(() => {
        localStorage.setItem("myCart", cart);
    }, [cart]);

function addItem() {
            setCart("item")   
    }

return (
<>
<button onClick={addItem}>Add</button>)
</>
);
}

Any idea if it's possible to use localStorage on a NextJS static site or if I'm doing something wrong?

Thanks!

3 Answers

I've used use-persisted-state:

import createPersistedState from 'use-persisted-state';

const useCartState = createPersistedState('cart');

export default function Category() {
     
  const [cart, setCart] = useCartState('');

  function addItem() {
    setCart("item");
  }

  return (
    <>
      <button onClick={addItem}>Add</button>)
    </>
  );
}

localStorage is available through the window object. Since Next.js runs through the code twice, once in the server during SSR and once in the client, it won't be able to access the window object during SSR, hence the error.

You'd want to check if the window object is present and then access the localStorage like this —

!!window ? window.localStorage.getItem("myCart") : ""

Check if window object is present in the environment, if present get the value from localStorage, else return empty string.

this is how to do it using a technique called lazy initialization. create the function on top of the component.

const getInitialState =()=>localStorage.getItem("myCart");
export default function Category() {

const [cart, setCart] = useState(
        getInitialState || ""
    );

 useEffect(() => {
        localStorage.setItem("myCart", cart);
    }, [cart]);

function addItem() {
            setCart("item")   
    }

return (
<>
<button onClick={addItem}>Add</button>)
</>
);
}

Related