next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Unable to stop AppContext(Context API) from rendering server side | Local Storage not defined or ClassNames are different client and server side

Open krishnaacharyaa opened this issue 1 year ago • 2 comments

Link to the code that reproduces this issue

https://github.com/krishnaacharyaa/nextjs-explore

To Reproduce

  1. Clone & Fork the project
  2. npm install
  3. npm run dev
  4. ReferenceError: localStorage is not defined at getSavedData (./context/appContext.tsx:27:13) at AppContextProvider (./context/appContext.tsx:50:79)

Though it is taken care by wrapping it in (typeof window != undefined) , still the server throws error undefined and even if i have managed it somehow, It throws error saying cilent side and server side css are different.

Though the client side everything is fine and the data is fetched from the localstorage eventually, How to get away with this error? How do I stop this context from rendering in the server side? And what is the correct way of handling this error.

I am open to all the reponses.

Current vs. Expected behavior

I do not expect the server to throw error localstorage is not defined. because at the end of the day it is able to fetch data from the localstorage.

And even after wrapping it in (window!=undefined) it is throwing the error

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Enterprise
Binaries:
  Node: 20.11.0
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 14.1.0
  eslint-config-next: 14.1.0
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router, Data fetching (gS(S)P, getInitialProps)

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

No response

krishnaacharyaa avatar Jan 30 '24 04:01 krishnaacharyaa

Hi,

You have this line:

const [items, setItems] = useState(getSavedData() || initialData || []);

JavaScript works with Applicative Order, so getSavedData() is called.

Internally that functions does this check:

	const getSavedData = () => {
		var savedData = null;
		if (typeof window != undefined) {
			savedData = localStorage.getItem(STORE_SELECTION)
				? JSON.parse(localStorage.getItem(STORE_SELECTION))
				: null;
			return savedData;
		}
		return savedData;
	};

Never mind the usage of var, let's look at this if branch:

		if (typeof window != undefined) {

That's not the check you want!

Welcome to Node.js v18.18.0.
Type ".help" for more information.
> typeof window != undefined
true

As you can see, in Node, this if branch does run. You want something like if (typeof window !== 'undefined'), because the typeof operator returns a string.

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof

icyJoseph avatar Jan 30 '24 13:01 icyJoseph

You also have this:

  • https://github.com/krishnaacharyaa/nextjs-explore/blob/main/app/page.tsx#L7

That won't fly when you try to build the application. Please refer to these documentation entries, where this issue has been expanded upon:

  • https://nextjs-faq.com/fetch-api-in-rsc
  • https://nextjs-faq.com/fetch-api-in-getserversideprops

icyJoseph avatar Jan 30 '24 13:01 icyJoseph

Thank you bunch @icyJoseph for your valuable time and the useful links. I solved the issue by using next/dynamic and giving option ssr: false for the AppContextProvider

https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading#importing-client-components

Can I kindly draw your attention to https://github.com/vercel/next.js/issues/61482

krishnaacharyaa avatar Feb 01 '24 12:02 krishnaacharyaa

Hi, yeah I just answered there.

Please don't forget to close the issue, if you think it is resolved.

icyJoseph avatar Feb 01 '24 13:02 icyJoseph

Yeah sure, Thank you @icyJoseph for your answer and time, much appreciated

krishnaacharyaa avatar Feb 01 '24 13:02 krishnaacharyaa

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Feb 16 '24 00:02 github-actions[bot]