Home > Mobile >  ReferenceError: localStorage is not defined Next.js app
ReferenceError: localStorage is not defined Next.js app

Time:08-26

I have a Next.js app

This is one of my page/component looks like

import React from "react";
import { SomeLocalStorageComponent } from "some-external-lib";

const MyComponent = () => {
const isBrowser = typeof window !== "undefined"
{
    if (isBrowser) {
        <SomeLocalStorageComponent></SomeLocalStorageComponent>
    }
 }

};

export default MyComponent;

This is throwing the below run time error

Server Error
ReferenceError: localStorage is not defined

Here SomeLocalStorageComponent is an external library component which is dependant on a localStorage variable

When this SomeLocalStorageComponent is used in a React app, it functions as expected however when I'm consuming this into Next.js app it throws the error.

how to get rid of this error?

Please suggest. Thanks!

CodePudding user response:

If you try to access localStorage normally inside of a component in Next.js like this

import React from 'react';

const MyComponent = () => {
  console.log(localStorage.getItem('some-data'))
};

you'll get this error:

Server Error
ReferenceError: localStorage is not defined

This is because you're accessing localStorage before the page has fully loaded. You should try accessing localStorage inside a useEffect hook,

import React, { useEffect } from 'react';

const MyComponent = () => {
  useEffect(() => {
    console.log(localStorage.getItem('some-data'))
  }, [])
};

CodePudding user response:

You can use next/dynamic:

import dynamic from 'next/dynamic'

const SomeLocalStorageComponent = dynamic(() => import('some-external-lib'), {
  ssr: false,
})

It will disable ssr for imported component

If your external library exports multiple components you can do something like this:

const SomeLocalStorageComponent = dynamic(
    async () => (await import('some-external-lib').SomeExportedComponent,
    {
        ssr: false,
    }
)

You should do above for each component you want to disable ssr

And if you want to have ssr in imported component you can import it normally:

import { TestComponent } from "some-external-lib"

Also protip:

You can export component with no ssr to a new file:

//TestComponentNoSsr.js

const TestComponent = dynamic(
    async () => (await import('some-external-lib').TestComponent,
    {
        ssr: false,
    }
)

export default TestComponent
  • Related