1

In my Next.js app I have a navbar , and it displays a different UI based on if a user is logged in or not. I decided to keep track of if user is logged in by reading a cookie. Here is a relevant part of code:

export default function Navbar() {
  let loggedin
  if (typeof window !== undefined) {
    loggedin = getCookie('auth')
  }
  return (
   {!loggedin?
    // one UI logic
    :
   //different UI logic
  }
 )
}

getCookie is a simple function that is using npm package js-cookie :

export const getCookie = (name) => cookies.get(name)

My issue is that when I hard reload a page or load it for the first time I get this warning in my console and some part of CSS is broken :

react-dom.development.js:88 Warning: Expected server HTML to contain a matching <div> in <div>.
    in div (at Navbar.js:68)
    in div (at Navbar.js:67)
    in ul (at Navbar.js:34)
    in div (at Navbar.js:26)
    in nav (at Navbar.js:25)
    in Navbar (at Layout.js:12)
    in div (at Layout.js:11)
    in Layout (at pages/index.js:18)
    in Home (at _app.js:13)
    in UserProvider (at _app.js:13)
    in MyApp
    in ErrorBoundary (created by ReactDevOverlay)
    in ReactDevOverlay (created by Container)
    in Container (created by AppContainer)
    in AppContainer
    in Root

After I navigate on a client to any other page this warning does not appear any more and CSS is fixed. I was able to pinpoint the issue, and if I comment out this part in my code the error is gone :

 if (typeof window !== undefined) {
    loggedin = getCookie('auth')
  }

Of course, my navbar logic is broken in this case. I realize that there is no cookies on the server side, therefore to prevent it running on the server I check where the code is executed in this line if (typeof window !== undefined){} . However, by adding console.log() inside of the if statement I can see that it's running on the server too.

What am I doing wrong? Why do I get this warning and have some broken CSS? Why is if statement running on the server in this case? I appreciate any help.

Noob
  • 2,247
  • 4
  • 20
  • 31
  • Why do you use this? `if (typeof window !== undefined)` – Tasos Sep 29 '20 at 11:56
  • @TasosBu it's nextjs and there is no `window` object on the server side. I want to run this code only on the client, therefore, this is the check for it. – Noob Sep 29 '20 at 12:04
  • Oh, I get it. Isn't there a better way to to check if it runs on the browser or the server? – Tasos Sep 29 '20 at 12:05
  • @TasosBu I don't think so – Noob Sep 29 '20 at 12:10
  • @Noob as a side note, `typeof window !== undefined` will always be true, because `typeof` returns a string. If you check that `typeof window !== 'undefined'` then you'll get the results you were looking for (execute in the browser and not the server) – drukepple Feb 18 '21 at 21:04

1 Answers1

1

I believe this will not be needed if you put the cookie check inside the useEffect like this:

import React, { useState } from 'react'

export default function Navbar() {
  const [loggedin, setLoggedin] = useState(false)

  useEffect(() => {
    const cookie = getCookie('auth')
    setLoggedin(cookie)
  }, [])
  
  return (
   {!loggedin?
    // one UI logic
    :
   //different UI logic
  }
 )
}

Can you give it a shot and let me know if it works?

Tasos
  • 1,880
  • 13
  • 19
  • yes it works, because useeffect is running only on a client only. However, I don't understand what is going on with my code. – Noob Sep 29 '20 at 12:37
  • I found this post that may answer your question: https://stackoverflow.com/a/53539693/5605822 – Tasos Sep 29 '20 at 12:41