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

What is the best way to dynamically display a React Form using Next.js?

As a novice in web development, I am currently tackling a small project using next js. The task at hand involves creating a registration form for restaurants with numerous input fields, prompting me to consider splitting the form into two separate pages. O ...

The element is anchored within a div, but its position is dependent on a JavaScript script

I am dealing with a situation where I have a div named "Main_Card" containing text and an icon. When the icon is clicked, it moves the "Main_Card" along with everything inside of it. The challenge arises when I need to set the icon's position as eithe ...

Filtering properties of objects in Vue

I am currently dealing with an array of objects that represent continents: data() { return { continents: [ { name: "South America", countries: [ { name: "P ...

Why does my JSON variable contain "type" and "data" values instead of something else?

After using JSON.stringify() on my object to save it to a file, I noticed that one of the parameters does not have the expected string value assigned. Instead, it has a "type" and "data". Code: fs.writeFileSync('myjson.json', JSON.stringify(myjs ...

React Stripe checkout with multiple products listed

I've successfully implemented a React app with Stripe checkout functionality. However, I'm facing an issue where I need to pass multiple items for payment in the checkout process. Currently, it works fine for a single item, but I have an array of ...

Replace the hyphen with a comma using JavaScript

Looking for a way to modify a string like this: "PALS español K- add-on" by replacing the - with ,. The desired output should be: "PALS español K, add-on" Is there a JavaScript solution to achieve this task? ...

Physically eliminate (and obliterate) a component from keep-alive

Is there a way to access and programmatically unmount a component instance loaded from Vue Route and persisted using <keep-alive> and <component>? I am working on a dynamic tab system where each tab renders a URL which displays its declared com ...

Using an npm package in client-side JavaScript

I've been exploring client-side GitHub packages recently and came across developers mentioning that the packages can be downloaded using npm. This confuses me as I thought these were client-side JavaScript packages. They also mentioned something about ...

Is there a way to organize a list of arrays within a loop based on a specific index within each array in JavaScript?

Greetings, I am currently facing an issue with sorting a specific object of arrays. The structure is as follows: Allow me to provide a clearer example - I am receiving a string from an AJAX call formatted like this: "name|price|blah|blah@name|price|blah| ...

Display modal after drop-down selection, triggered by API response

Currently, I am working on integrating an API to enable users to make payments through a modal. Users should be able to enter an amount and select a payment frequency. I have successfully extracted various payment frequencies from the API response and pop ...

How can I receive user input in JavaScript while incorporating three.js?

I am currently exploring the functionalities of this three.js example () and I am interested in enabling users to input specified X, Y, and Z positions for boxes dynamically. Initially, I considered utilizing a JavaScript prompt like below: var boxes = p ...

Mantine UI: Elevate Your Component Library Experience

I am in the process of creating a Component library for internal company projects, which will be packaged as an npm package. To kick things off, I am starting with Mantine and plan to incorporate customization using tailwind CSS. As a test, I have created ...

React Native error - "Invalid element type: expected a string or class/function, but received undefined" - encountering issue with importing a custom library?

Alright, I'm looking to make some modifications to this library, so I am attempting to import the non-transpiled version by downloading the repository and importing it from here: https://github.com/nicotroia/react-native-floating-action-menu#readme A ...

ReactJS: Oops! Looks like there's an issue with the element type - it's invalid. We were expecting a string

I am in the process of setting up a basic server-side rendered React application. Listed below are the steps I have taken: Step 1: Creating a new React app using create-react-app: npx create-react-app my-ssr-app Step 2: Installing necessary dependencies: ...

Chatting with a Discord bot

I am currently working on a Discord bot that will execute specific functions based on the questions asked, most of which are yes or no queries. Upon responding with "yes," a particular function should be performed, while answering "no" would terminate t ...

Is incorporating RequireJS into an AngularJS project a valuable decision?

Is it true that AngularJS has its own module loading mechanism built-in and using RequireJS is unnecessary or even inefficient? I am working on an Angular project where the index.html file is becoming quite large. Would incorporating RequireJS help reduc ...

The route seems to be downloading the page instead of properly rendering it for display

I'm facing a simple issue with my Express page - when I navigate to the FAQ route, instead of displaying the page it downloads it. The index page loads fine, and the FAQ page is the only other page available at the moment. I am using EJS templating, a ...

Invoking a JavaScript function within a different JavaScript function

Is there a way to ensure that the JavaScript function works properly even when using a text editor? var editor = $('#CKEditor1').ckeditorGet(); editor.on("instanceReady", function () { this.document.on("keydown", function (event) { ...

Using Node Express.js to access variables from routes declared in separate files

Currently, I am in the process of developing a website with numerous routes. Initially, all the routes were consolidated into one file... In order to enhance clarity, I made the decision to create separate files for each route using the Router module. For ...

Maximizing the worth of itemtype using jQuery: A guide

My goal is to include an 'itemtype' attribute in the body tag, body.page-body.ng-scope.device-lg(itemscope='', itemtype='') I attempted the following method $('body').add(itemtype='t1'); Unfortunately, ...