# ReferenceError: localStorage is not defined in Next.js

> This error occurs because, from Next.js version 13, components are server-rendered by default. Learn how to fix this issue in just a few steps.

**URL:** https://sentry.io/answers/referenceerror-localstorage-is-not-defined-in-next-js/

---

## The Problem

In Next.js version 13+, you may have encountered the following error when trying to use the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) browser API if you used the `window.localStorage` property:

```
Error: window is not defined
```

You may have encountered the following error if using the `localStorage` property:

```
Error: localStorage is not defined
```

In a browser environment, `windows.localStorage` is the same as `localStorage`, and `localStorage` is a property of the global `window` object.

This error occurs because, from Next.js version 13, components are server-rendered by default. Components are pre-rendered into HTML on the server before being sent to the client. The `window` object is not available on the server.

## The Solution

We need to make sure that the code to get values from local storage and save values to local storage only runs on the client where the `window` object is defined. We can do this by using the `useEffect` hook in a Next.js [client component](https://nextjs.org/docs/app/getting-started/server-and-client-components) or by lazy loading the component.

To use browser APIs like the `window` object, create a client component by adding the React [`"use client"` directive](https://react.dev/reference/rsc/use-client) at the top of your component file, above your imports. Client components are pre-rendered on the server, like server components, for a fast initial payload.

The client component is then made interactive by adding event listeners to the static HTML. This process is called hydration. Client components render on the server and the client.

### Use `useEffect` in a Client Component

To make sure that the code using the `window` object is run on the client only, add it to a `useEffect` hook.

Below is an example counter component that stores a count state variable in local storage:

```javascript
"use client";

import { useState, useEffect } from "react";

export default function Counter() {
  const [count, setCount] = useState(null);

  useEffect(() => {
    const savedValue = window.localStorage.getItem("count");
    setCount(savedValue ? Number(savedValue) : 0);
  }, []);

  useEffect(() => {
    if (typeof count === "number") {
      window.localStorage.setItem("count", count);
    }
  }, [count]);

  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {typeof count === "number" ? count : <span>...</span>}
    </button>
  );
}
```

In this component, a button is rendered that increments the `count` state variable by 1 when it's clicked. The first `useEffect` hook gets the value for `count` from local storage or sets it to 0 if it has not been added to local storage yet. The second `useEffect` saves the value of the `count` variable to state when the useEffect's dependency, `count`, changes. This happens when the button is clicked.

### Lazy Load the Client Component and Disable SSR

Alternatively, you can [lazy load](https://nextjs.org/docs/pages/guides/lazy-loading) your client component and [disable pre-rendering on the server](https://nextjs.org/docs/app/guides/lazy-loading#skipping-ssr) so that it's only rendered on the client. This may increase the time taken for the page to initially load. This approach is useful when using a client-only library or when you want to defer loading the component until a specific action happens, such as the user clicking a button.

---

*Source: [sentry.io/answers/referenceerror-localstorage-is-not-defined-in-next-js/](https://sentry.io/answers/referenceerror-localstorage-is-not-defined-in-next-js/)*
