Search code examples
javascriptreactjsnext.jsreact-reduxlocal-storage

localStorage is not defined in next js


I am using next.js for frontend. I want to get user from localStorage, but as next.js is a server-side rendring, I can't get localStorage. What should I do so I can get localStorage?

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import authService from "./authService";

const getUserfromLocalStorage = localStorage.getItem("user")
  ? JSON.parse(localStorage.getItem("user"))
  : null;

const initialState = {
  user: getUserfromLocalStorage,
  isError: false,
  isLoading: false,
  isSuccess: false,
  message: "",
};

export const login = createAsyncThunk('auth/login', async (user, thunkAPI) => {
  try {
    return await authService.login(user);
  } catch (error) {
    return thunkAPI.rejectWithValue(error);
  }
});

export const authSlice = createSlice({
  name: "auth",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(login.pending, (state) => {
        state.isLoading = true;
      })
      .addCase(login.fulfilled, (state, action) => {
        state.isLoading = true;
        state.isSuccess = false;
        state.user = action.payload;
      })
      .addCase(login.rejected, (state, action) => {
        state.isLoading = false;
        state.isError = true;
        state.isSuccess = false;
        state.user = null;
      });
  },
});

export default authSlice.reducer;

enter image description here


Solution

  • That's because you are trying to access client side variable - window.localStorage on server where window doesn't exist.

    const getUserfromLocalStorage = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null;
    

    Here you should first check whether window is defined or not.

    if (typeof window !== 'undefined') {
      const getUserfromLocalStorage = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null;
    }
    

    OR you can check if window is defined using optional chaining

    const getUserfromLocalStorage = window?.localStorage?.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null;
    

    Here more "React" like solution would be to use hooks like useEffect to perform this action.

    import { useEffect } from "react";
    
    useEffect(() => {
      const getUserfromLocalStorage = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null;
    }, []);