Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next Auth useSession returning undefined on initial page load

I have an issue where my Next Auth useSession function is returning undefined on intial page load but works when hitting refresh on the page. Here is the code:

<Navigation />

import { useSession, signIn, signOut } from 'next-auth/client'
export default function Navigation() {

  const [session] = useSession()
  return (
    <section className="navigation">
        {!session ? (
            <div onClick={handleSignin} className="loginLink">Login</div>
        ) : ( //Do Logged ins stuff )}
    </section>
  )
}

<Layout>

const Layout = (layoutProps) => (
  <motion.main initial="hidden" animate="enter" exit="exit" variants={variants}>
    <div className="Layout">
      <Head>
        <title>My Site</title>
      </Head>
      <Navigation />
      <div className="Content">{layoutProps.children}</div>
      <Footer />
    </div>
  </motion.main>
)

index.js

class Home extends React.Component {
  render() {
    return (
      <Layout>
         //Home page stuff
      </Layout>
    )
  }
}

export default Home

App.js

render() { const { Component } = this.props

return (
  <>
    <GlobalStyles />
    <AnimatePresence
      exitBeforeEnter
      initial={false}
      onExitComplete={() => window.scrollTo(0, 0)}
    >
      <Component key={Router.router != null ? Router.router.asPath : '/null'} {...this.props} />
    </AnimatePresence>
  </>
)

}

Simple stuff. Not sure what's going on. I hope that's enough to work with.

like image 399
MomasVII Avatar asked Oct 14 '25 15:10

MomasVII


2 Answers

The same thing happened to me. Here is how I solved it. From Next-Auth docs:

useSession() returns an object containing two values: data and status:

data: This can be three values: Session / undefined / null. When the session hasn't been fetched yet, data will be undefined. In case it failed to retrieve the session, data will be null. In case of success, data will be Session.

You get undefined because the session hasn't been fetched yet. You can solve it by using useEffect and adding "session" to its dependencies:

import { useSession, signIn, signOut } from "next-auth/client";

export default function Navigation() {
  const [session] = useSession();

  useEffect(() => {}, [session]);

  return (
    <section className="navigation">
      {!session ? (
        <div onClick={handleSignin} className="loginLink">
          Login
        </div>
      ) : (
        <p>Do logged ins stuff</p>
      )}
    </section>
  );
}

When the session finishes getting fetched, it will trigger a re-render and change the content. With this approach it is very likely that the content you want to hide will show in the screen while the session is getting fetched.

With that being said, from the Next-Auth docs, it could be better to use "getServerSession" in getServerSideProps instead of useSession(). With this approach your session data will be available from the start and you won't have the need to make another request and re-render.

Hope it helped you.

like image 185
Francisco Ceballos Avatar answered Oct 17 '25 06:10

Francisco Ceballos


Try implementing Provider in App.js. Here's an example from the documentation for v3: https://next-auth.js.org/v3/getting-started/example#add-session-state

//pages/_app.js
import { Provider } from "next-auth/client"

export default function App({ Component, pageProps }) {
  return (
    <Provider session={pageProps.session}>
      <Component {...pageProps} />
    </Provider>
  )
}
like image 43
torkue Avatar answered Oct 17 '25 06:10

torkue