Skip to content
next

How to use Local Storage in Next.js

Apr 4, 2023Abhishek EH4 Min Read
How to use Local Storage in Next.js

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

1ReferenceError: localStorage is not defined

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:

1npx create-next-app next-local-storage

Update index.js with the following code:

index.js
1import { useState } from "react"
2
3export default function Home() {
4 let value
5 // Get the value from local storage if it exists
6 value = localStorage.getItem("favoriteNumber") || ""
7
8 // Set the value received from the local storage to a local state
9 const [favoriteNumber, setFavoriteNumber] = useState(value)
10
11 // When user submits the form, save the favorite number to the local storage
12 const saveToLocalStorage = e => {
13 e.preventDefault()
14 localStorage.setItem("favoriteNumber", favoriteNumber)
15 }
16
17 return (
18 <div>
19 <label htmlFor="number">Your favorite number</label>
20 <form onSubmit={saveToLocalStorage}>
21 <input
22 id="number"
23 value={favoriteNumber}
24 onChange={e => setFavoriteNumber(e.target.value)}
25 />
26 <input type="submit" value="Save" />
27 </form>
28 </div>
29 )
30}

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.

1if (typeof window !== "undefined") {
2 value = localStorage.getItem("favoriteNumber") || ""
3}

Using try-catch block

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

1try {
2 value = localStorage.getItem("favoriteNumber") || ""
3} catch (error) {}

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.

1import { useEffect, useState } from "react"
2
3export default function Home() {
4 // Set the value received from the local storage to a local state
5 const [favoriteNumber, setFavoriteNumber] = useState("")
6
7 useEffect(() => {
8 let value
9 // Get the value from local storage if it exists
10 value = localStorage.getItem("favoriteNumber") || ""
11 setFavoriteNumber(value)
12 }, [])
13
14 // When user submits the form, save the favorite number to the local storage
15 const saveToLocalStorage = e => {
16 e.preventDefault()
17 localStorage.setItem("favoriteNumber", favoriteNumber)
18 }
19
20 return (
21 <div>
22 <label htmlFor="number">Your favorite number</label>
23 <form onSubmit={saveToLocalStorage}>
24 <input
25 id="number"
26 value={favoriteNumber}
27 onChange={e => setFavoriteNumber(e.target.value)}
28 />
29 <input type="submit" value="Save" />
30 </form>
31 </div>
32 )
33}

Using a custom hook

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

useLocalStorage.js
1import { useState } from "react"
2
3const useLocalStorage = (key, initialValue) => {
4 const [state, setState] = useState(() => {
5 // Initialize the state
6 try {
7 const value = window.localStorage.getItem(key)
8 // Check if the local storage already has any values,
9 // otherwise initialize it with the passed initialValue
10 return value ? JSON.parse(value) : initialValue
11 } catch (error) {
12 console.log(error)
13 }
14 })
15
16 const setValue = value => {
17 try {
18 // If the passed value is a callback function,
19 // then call it with the existing state.
20 const valueToStore = value instanceof Function ? value(state) : value
21 window.localStorage.setItem(key, JSON.stringify(valueToStore))
22 setState(value)
23 } catch (error) {
24 console.log(error)
25 }
26 }
27
28 return [state, setValue]
29}
30
31export default useLocalStorage

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

index.js
1import useLocalStorage from "@/hooks/useLocalStorage"
2import { useState } from "react"
3
4export default function Home() {
5 // Get the value from local storage if it exists
6 const [value, setValue] = useLocalStorage("favoriteNumber", "")
7
8 // Set the value received from the local storage to a local state
9 const [favoriteNumber, setFavoriteNumber] = useState(value)
10
11 // When user submits the form, save the favorite number to the local storage
12 const saveToLocalStorage = e => {
13 e.preventDefault()
14 setValue(favoriteNumber)
15 }
16
17 return (
18 <div>
19 <label htmlFor="number">Your favorite number</label>
20 <form onSubmit={saveToLocalStorage}>
21 <input
22 id="number"
23 value={favoriteNumber}
24 onChange={e => setFavoriteNumber(e.target.value)}
25 />
26 <input type="submit" value="Save" />
27 </form>
28 </div>
29 )
30}

Source code and Demo

You can view the complete source code here and a demo here

Do follow me on twitter where I post developer insights more often!

© 2024 CodingDeft.Com