I am trying to build a website using NextJS v13 and Next Auth v4. Whenever a page/component is loaded, the session is not returned in the first render when using useSession
hook and because of this, many components don’t work like they should…
For instance, the following code should load the questions for authenticated users:
'use client'
import { useEffect, useState } from 'react'
import { Question } from '@prisma/client'
import { useSession } from 'next-auth/react'
function QuestionPage() {
const { data: session } = useSession() // this is null
const [questions, setQuestions] = useState<Question[]>([])
const [questionStatus, setQuestionStatus] = useState('');
useEffect(() => {
console.log('Session: ', session)
if (!session) return;
setQuestionStatus('Loading questions...');
fetch('/api/questions')
.then((res) => res.json())
.then((data) => {
setQuestions(data.questions)
setQuestionStatus('');
})
}, [])
return (
<div>
<p>{questionStatus}</p>
{questions && questions.map(question => {
<p key={question.id}>{question.title}</p>
})}
</div>
)
}
This is my ProviderWrapper
component that wraps the main app:
'use client'
import QuestionContextWrapper from '@/context/QuestionContext'
import { SessionProvider } from 'next-auth/react'
export const metadata = {
title: 'My App',
description: 'My description',
}
export default function ProvidersWrapper({ children }: { children: React.ReactNode }) {
return (
<SessionProvider>
<QuestionContextWrapper>
{children}
</QuestionContextWrapper>
</SessionProvider>
)
}
And this is the layout.tsx
file:
import './globals.css'
import Header from '@/components/Header'
import ProvidersWrapper from './ProvidersWrapper'
import Footer from '@/components/Footer'
export const metadata = {
title: 'My app',
description: 'My description',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<ProvidersWrapper>
<Header />
{children}
<Footer />
</ProvidersWrapper>
</body>
</html>
)
}
Anyone knows why is next-auth
behaving like this?
2
Answers
After some research and due to the @Thusithz's answer, I have found this guide to implement proper authentication using Next Auth and TypeScript. So I changed my code to the following and it worked.
I have renamed
/src/components/PriverWrapper.tsx
tosrc/context/AuthProvider.tsx
and changed the code as well to the following:And then applied this to the
/src/app/layout.tsx
file wrapping the node withAuthProvider
and passing thesession
variable:So, this works as expeted.
Initial load session will be undefined since it’s not pass to provider. Try to pass existing session to provider like below.