Navigating Next.js: Mastering the art of localStorage Access

Currently, I am developing my first member area using next.js. My goal is to store some data in localStorage (such as token, expiresAt, userInfo), which will eventually be moved to an http-only cookie.

The code below is generating the error: "LocalStorage is not defined":

const AuthProvider = ({ children }) => {
   
   const token = localStorage.getItem("token");
   const userInfo = localStorage.getItem("userInfo");
   const expiresAt = localStorage.getItem("expiresAt");
   

  const [authState, setAuthState] = useState({
    token,
    expiresAt,
    userInfo: userInfo ? JSON.parse(userInfo) : {},
  });

  const setAuthInfo = ({ token, userInfo, expiresAt }) => {
    localStorage.setItem("token", token);
    localStorage.setItem("userInfo", JSON.stringify(userInfo));
    localStorage.setItem("expiresAt", expiresAt);

    setAuthState({
      token,
      userInfo,
      expiresAt,
    });
  };

I have attempted to resolve it by implementing the following snippet:

if (typeof window !== 'undefined') {
const token = localStorage.getItem("token");
const userInfo = localStorage.getItem("userInfo");
const expiresAt = localStorage.getItem("expiresAt");}

However, this resulted in the error message "token is undefined". I then tried declaring the variables const token, const userInfo, and const expiresAt globally, but encountered the error: "Unexpected token o in JSON at position 1".

I am struggling with this issue and would appreciate any assistance. Thank you!

Answer №1

After tinkering around with the code a bit more and thanks to the assistance of fellow developers, I finally cracked the solution:

const AuthProvider = ({ children }) => {
  let token = "";
  let userInfo = "";
  let expiresAt = "";

  if (typeof window !== "undefined") {
    token = localStorage.getItem("token");
    userInfo = localStorage.getItem("userInfo");
    expiresAt = localStorage.getItem("expiresAt");
  }

...

The conditional statement ensures that the code only runs when the window is accessible. Additionally, I had to declare the variables (let token, let expiresAt, and let userInfo) outside of the conditional statement so they could be accessed in other parts of the code.

This tip might come in handy for someone facing a similar issue.

Answer №2

Here is a solution that should be effective

if (typeof window !== 'undefined') {
  let accessToken = localStorage.getItem("accessToken");
  let userCredentials = localStorage.getItem("userCredentials");
  let expirationTime = localStorage.getItem("expirationTime");
}

If you're encountering the error accessToken is not defined or unexpected character, it may be due to either the absence of the key accessToken in your localStorage or incorrect data assignment.

Answer №3

useEffect hook specifically runs on the client side, ensuring that storage is defined when accessed inside of it. Take advantage of this custom hook to handle storage functionality:

export default function useStorage(key, type = "sessionStorage") {
  const [value, setValue] = useState();

  // Retrieve initial data from storage
  useEffect(() => {
    const storage = type === "sessionStorage" ? sessionStorage : localStorage;
    setValue(storage.getItem(key));
  }, [key, type]);

  // Save data to storage
  useEffect(() => {
    // Avoid overwriting existing value during first render
    if (value !== undefined) {
      const storage = type === "sessionStorage" ? sessionStorage : localStorage;
      storage.setItem(key, value);
    }
  }, [key, value, type]);

  return [value, setValue];
}

Usage Example:

const [myValue, setMyValue] =  useStorage("my_value")

Answer №4

Implementing localStorage functionality in Next JS 13

Discover how to manage localStorage operations like creating, updating, and removing tokens in Next JS with ease.

const [accessToken, setAccessToken] = useState(null);

useEffect(() => {
  if (typeof window !== "undefined" && window.localStorage) {
    let token = localStorage.getItem("access_token");
    setAccessToken(token);
  }
}, [setAccessToken]);

const createAccessToken = (newToken) => {
  if (typeof window !== "undefined" && window.localStorage) {
    localStorage.setItem("access_token", newToken);

    let token = localStorage.getItem("access_token");

    setAccessToken(token);
  }
};

const removeAccessToken = () => {
  if (typeof window !== "undefined" && window.localStorage) {
    localStorage.removeItem("access_token");
    setAccessToken(null);
  }
};

const logoutUser = useCallback(() => {
  removeAccessToken();
}, []);

Additional Resources

Answer №5

If you're looking to enhance the functionality of your project, one suggestion is to incorporate the AuthProvider component through dynamic imports with the ssr option set to false. Here's an example:

const AuthProvider = dynamic(() => import("AuthProvider.tsx"), {ssr:false})

Once imported dynamically, you can utilize the AuthProvider as needed throughout your application. This approach has proven successful for me in similar scenarios.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How do I send a 404 error in Node JS Express when a third party API receives a bad request?

I've set up a Node JS server with a route handler that sends a request to a third-party API to retrieve a username: app.get('/players/:player', apiLimiter, function(request, response) { const player = request.params.player; const api_url = ...

Updating a specific element within a list using AWS DynamoDB

In my DynamoDB database, I have the following table structure: { UserId: "123456", Orders: [ { OrderId: "ORD123", OrderRef: "Christmas presents", OrderStatus: 0, ...

Utilizing the power of AWS Lambda in conjunction with moment JS to generate unique

My current time zone is GMT+8, and the AWS region I am using is Singapore (ap-southeast-1). I am facing an issue where there are discrepancies in date calculations between my local machine and when I deploy my code on AWS Lambda. My goal is to ensure that ...

The onCreated listener function in the jBox Modal dialog is experiencing issues and not functioning properly after the first use

I am using jBox from the URL: . Every time I click on a link, a modal is created. The first time the modal is created, listeners for the buttons on that modal are properly added in the "onCreated" attribute and work when clicked. However, from the second ...

Encountering the "excessive re-renders" issue when transferring data through React Context

React Context i18n Implementation i18n .use(initReactI18next) // passes i18n down to react-i18next .init({ resources: { en: { translation: translationsEn }, bn: { translation: translationsBn }, }, lng: "bn ...

Share JSON data across functions by calling a function

I am currently working on a project where I need to load JSON using a JavaScript function and then make the loaded JSON objects accessible to other functions in the same namespace. However, I have encountered some difficulties in achieving this. Even after ...

Using React to integrate Zurb Foundation's slider by binding moved.zf.slider

Update: I have included the complete code as requested. There are a few modifications from the original version. I am attempting to integrate the foundation slider with react and ES6. The slider is supposed to trigger an event named moved.zf.slider when i ...

The Jquery code encountered an issue where it was unable to access the property 'length' of an undefined

My goal is to submit a form using jQuery and AJAX, which includes file upload functionality. The challenge I'm facing is that the forms are dynamically created, so I need to identify which form was clicked and retrieve its input values. $(document).r ...

What is the best way to display an error message when a necessary field is left empty?

I am currently utilizing a plugin to validate my form. My goal is to display an error message on the button when clicked, as all fields in my form are required and need validation. Despite attempting the code below, it hasn't been successful: <Fo ...

Unexpected TypeError thrown by a simple react-cube-navigation demonstration

Looking to utilize the react-cube-navigation component, available here. Encountering a TypeError when attempting to run the provided example, React throws an error: TypeError: props.rotateY.to(function (x) { return "scale is not a function. ( ...

Determining the necessary data to send via ajax for a particular issue

Currently, I am learning JavaScript and have encountered another challenge along the way. I am looking for assistance in understanding the concept, whether it is a solution in jQuery or Angular. I have two types of tasks in my HTML - audio or graphic. The ...

Optimizing the particle rendering speed for HTML5 <canvas> elements

Currently conducting an experiment to enhance the maximum particle count before frame-rates begin to decrease in HTML5 Canvas. Utilizing requestAnimationFrame and employing drawImage from a canvas as it appears to be the most efficient method for image re ...

Retrieving an attribute through the act of clicking a button

How can I retrieve the rel attribute value when clicking on a button with the class selector? <button class="nameClass" rel="relName">Content</button> I am attempting to achieve this by: $(".nameClass").click(function(){ // Here is where ...

using the information from the child array within a v-if condition

I'm struggling to extract data from a child array and utilize it in my v-if condition. Below are my data and code. Any assistance would be appreciated, even if it's just pointers to the right documentation. <div class='post' v-for= ...

add the closing </div> tag using jquery only

Having a slight issue here, it seems that jQuery is being overly clever. Within my HTML code, I am attempting to insert this string into a div container: </div><div class="something"> You'll notice that the closing tag comes first, foll ...

What is the best way to generate unique mousedown callbacks on the fly?

My goal is to create multiple divs, each with a unique mousedown callback function. However, I want each callback function to behave differently based on the specific div that is clicked. Below is the code I have been using to create the divs and set the ...

What is the process of establishing a connection to a web service using Meteor or Node.js?

Currently working on developing a package that interfaces with a web service (either through nodejs or meteor). The web service will be delivering real-time data, so I am in need of a mechanism like a listener or trigger event that can alert me when new da ...

What is the best way to display a page within a div when clicking in Yii?

I'm trying to use the jQuery function .load() to load a page into a specific div. Here's my code: <a href="" onclick="return false;" id="generalinfo"> <div class="row alert alert-danger"> <h4 class="text-center">Gen ...

Deleting the stylesheet exclusively within the confines of the React application window

Here is an image that will help illustrate the issue: https://i.stack.imgur.com/VA7fw.png If you want to check out the code sandbox for this problem, you can visit: https://codesandbox.io/s/annoying-stylesheet-2gpejc?file=/public/index.html I am current ...

The oncanplaythrough event is not functioning properly in Internet Explorer

I am facing an issue where the beep sound trigger upon receiving an API response works perfectly in Chrome and Firefox browsers, but unfortunately, it does not work in Internet Explorer. if ($scope.totalQueueList) { var audio = new Audio(); audio.s ...