How to use Local Storage in Next.js

Valentsea
Total
0
Shares

Have you received the following error while using local storage in Next.js?

ReferenceError: localStorage is not defined
Enter fullscreen mode

Exit fullscreen mode

In this article, we will see how to use local storage in Next.js



Project set up

Create a Next.js application using the following command:

npx create-next-app next-local-storage
Enter fullscreen mode

Exit fullscreen mode

Update index.js with the following code:

import { useState } from "react"

export default function Home() {
  let value
  // Get the value from local storage if it exists
  value = localStorage.getItem("favoriteNumber") || ""

  // Set the value received from the local storage to a local state
  const [favoriteNumber, setFavoriteNumber] = useState(value)

  // When user submits the form, save the favorite number to the local storage
  const saveToLocalStorage = e => {
    e.preventDefault()
    localStorage.setItem("favoriteNumber", favoriteNumber)
  }

  return (
    <div>
      <label htmlFor="number">Your favorite numberlabel>
      <form onSubmit={saveToLocalStorage}>
        <input
          id="number"
          value={favoriteNumber}
          onChange={e => setFavoriteNumber(e.target.value)}
        />
        <input type="submit" value="Save" />
      form>
    div>
  )
}
Enter fullscreen mode

Exit fullscreen mode

Now if you run the code, you will get the following error:

ReferenceError: localStorage is not defined



Why does the error occur?

The error occurs because the code gets compiled in the server (in localhost or server-side rendering in production), localStorage object does not exist.



The fix

There are multiple ways in which it can be fixed.



Checking if the window is defined

localStorage is an object inside the window object. The window object will not be defined in the server and hence the localStorage code will not be executed in the server.

if (typeof window !== "undefined") {
  value = localStorage.getItem("favoriteNumber") || ""
}
Enter fullscreen mode

Exit fullscreen mode



Using try-catch block

We can use a try-catch block to surround the localStorage access:

try {
  value = localStorage.getItem("favoriteNumber") || ""
} catch (error) {}
Enter fullscreen mode

Exit fullscreen mode



Using a useEffect hook

You can use a useEffect hook to get the localStorage content. The useEffect hook will not be run in the server and hence no possibility of the error.

import { useEffect, useState } from "react"

export default function Home() {
  // Set the value received from the local storage to a local state
  const [favoriteNumber, setFavoriteNumber] = useState("")

  useEffect(() => {
    let value
    // Get the value from local storage if it exists
    value = localStorage.getItem("favoriteNumber") || ""
    setFavoriteNumber(value)
  }, [])

  // When user submits the form, save the favorite number to the local storage
  const saveToLocalStorage = e => {
    e.preventDefault()
    localStorage.setItem("favoriteNumber", favoriteNumber)
  }

  return (
    <div>
      <label htmlFor="number">Your favorite numberlabel>
      <form onSubmit={saveToLocalStorage}>
        <input
          id="number"
          value={favoriteNumber}
          onChange={e => setFavoriteNumber(e.target.value)}
        />
        <input type="submit" value="Save" />
      form>
    div>
  )
}
Enter fullscreen mode

Exit fullscreen mode



Using a custom hook

You can use a custom hook to access local storage as well

import { useState } from "react"

const useLocalStorage = (key, initialValue) => {
  const [state, setState] = useState(() => {
    // Initialize the state
    try {
      const value = window.localStorage.getItem(key)
      // Check if the local storage already has any values,
      // otherwise initialize it with the passed initialValue
      return value ? JSON.parse(value) : initialValue
    } catch (error) {
      console.log(error)
    }
  })

  const setValue = value => {
    try {
      // If the passed value is a callback function,
      //  then call it with the existing state.
      const valueToStore = value instanceof Function ? value(state) : value
      window.localStorage.setItem(key, JSON.stringify(valueToStore))
      setState(value)
    } catch (error) {
      console.log(error)
    }
  }

  return [state, setValue]
}

export default useLocalStorage
Enter fullscreen mode

Exit fullscreen mode

In index.js, you can use it as follows:

import useLocalStorage from "@/hooks/useLocalStorage"
import { useState } from "react"

export default function Home() {
  // Get the value from local storage if it exists
  const [value, setValue] = useLocalStorage("favoriteNumber", "")

  // Set the value received from the local storage to a local state
  const [favoriteNumber, setFavoriteNumber] = useState(value)

  // When user submits the form, save the favorite number to the local storage
  const saveToLocalStorage = e => {
    e.preventDefault()
    setValue(favoriteNumber)
  }

  return (
    <div>
      <label htmlFor="number">Your favorite numberlabel>
      <form onSubmit={saveToLocalStorage}>
        <input
          id="number"
          value={favoriteNumber}
          onChange={e => setFavoriteNumber(e.target.value)}
        />
        <input type="submit" value="Save" />
      form>
    div>
  )
}
Enter fullscreen mode

Exit fullscreen mode

Total
0
Shares
Valentsea

Learn JavaScript Array Reduce In 10 Minutes

JavaScript Simplified Course: https://javascriptsimplified.com By far the most difficult JavaScript array method to learn is the reduce method.…

You May Also Like