I am learning Nextjs for the first time, and have experimented by creating a small web app that allows someone to simply register then login. Everything works, except one small issue.
On the page, you can see your status. If you are logged in, it shows your username. If not, it provides a link to the sign in page.
This "Sign In" button is a part of the UserInfoBar
component, which is a SSR-component.
The problem is, that when you successfully login, and are redirected to the homepage with router.push('/')
, the "Sign In" link is not replaced with your username.
It is only when you refresh the page that your username will show.
I am really at a loss here. The only solution that I can think of is to make UserInfoBar
a client component, but then I would have to manually retrieve the session with a fetch
call.
Is there not a way to address this from the server side?
src/app/components/UserInfoBar.tsx
import React from 'react'
import Link from 'next/link'
import { getSession } from '../../lib/session'
export default async function UserInfoBar() {
let sessionData = getSession();
console.log('on the server')
console.log(sessionData)
return (
<div className="flex-grow text-right px-2 py-1 text-white">
{sessionData ?
sessionData.username :
<Link href="/signin" className='px-2 py-1 text-white '>Sign In</Link>}
</div>
)
}
src/app/Header.tsx
import React from 'react'
import Link from 'next/link'
import { Suspense } from 'react';
import UserInfoBar from './components/UserInfoBar'
export default function Header() {
return (
<header className='flex justify-center bg-slate-700 mb-7'>
<div className='flex max-width space-x-4 p-4'>
<Link href="/" className='px-2 py-1 text-white '>Home</Link>
<Link href="/decks" className='px-2 py-1 text-white '>Decks</Link>
<Link href="/signup" className='px-2 py-1 text-white '>About</Link>
<Suspense fallback={<p>loading...</p>}>
<UserInfoBar />
</Suspense>
</div>
</header>
)
}
src/app/page.tsx
import React from 'react'
export default function Page() {
return (
<div>
<h2 className="text-4xl font-extrabold text-slate-700">Demo</h2>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam faucibus erat a gravida ultricies.
</div>
)
}
src/app/lib/session.ts
import { cookies } from 'next/headers';
import jwt from 'jsonwebtoken'
export const getSession = () => {
const nxtCookies = cookies();
if (nxtCookies.has('session')) {
const cookie = nxtCookies.get('session');
let sessionData = jwt.verify(cookie.value, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) return false;
return user;
});
if (sessionData) return sessionData;
}
return false;
}