Home > Enterprise >  localStorage is not defined when building. Nextjs and Typescript
localStorage is not defined when building. Nextjs and Typescript

Time:04-11

I am building an app in NextJs using the Restcountries API. I am using redux for simulating a cart/fav-list component. But when I run "build" I am having an error saying that "localStorage is not defined"

import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "@redux-devtools/extension";
import thunk from "redux-thunk";
import { DefaultState } from "redux/reducers";
import reducer from "../reducers";

function saveToLocalStorage(state: DefaultState) {
  try {
    const localStorageState = JSON.stringify(state);
    localStorage.setItem("statePersist", localStorageState);
  } catch (e) {
    console.warn(e);
  }
}

function loadFromLocalStorage() {
  try {
    const localStorageState = localStorage.getItem("statePersist");
    if (localStorageState === null) return undefined;
    return JSON.parse(localStorageState);
  } catch (e) {
    console.warn(e);
  }
  return undefined;
}

const storeFactory = () => {
  const middlewares = [thunk];
  const reduxStore = createStore(
    reducer,
    loadFromLocalStorage(),
    composeWithDevTools(applyMiddleware(...middlewares))
  );
  reduxStore.subscribe(() => saveToLocalStorage(reduxStore.getState()));
  return reduxStore;
};

const midi = storeFactory();

export type Store = ReturnType<typeof storeFactory>;
export type RootState = ReturnType<typeof midi.getState>;
export default storeFactory;

CodePudding user response:

The issue you are seeing is because localStorage (aka window.localStorage) is not defined on the server side. Next server renders your components, so when that happens and it tried to access localStorage it can't find it. You'll have to wait until the browser renders it in order to use localStorage.

For other use cases you might have that use window in the future, you can check if (typeof window !== 'undefined')` which is a good way to check for whether you are on the client vs server.

const ISSERVER = typeof window === "undefined";
if (!ISSERVER) localStorage.setItem(key, value);

Or another approach would be to use Next's dynamic imports with ssr: false although this is usually only needed for more involved use cases (i.e. if you are importing a chart/graph library or something similar that uses window).

  • Related