change button in navbar on login
Answered
Large garden bumble bee posted this in #help-forum
Large garden bumble beeOP
Hello everyone. I am rather new to nextjs and I ran into a problem I am trying to fix for quite a while now so I would appreciate your help.
I have 2 components, my Navbar and my NavbarButton. the outcome i want is the following: if there is a session show the logout button, if there is no session dont show anything.
right now if i login into my application i have 2 solutions i am not happy with.
- serverside-component: if i make the navbar a serverside component button does not show after a successful login until i refresh the page
- clientside-component: if i make the navbar a client side component the button does show immediately and i dont need to refresh the page but every time i refresh the button disappears for a short time
I will put the code for the server- and clientside navbar and my navbar button in the next messages. I am not sure, if this is all the code you need but if not i will gladly provide you with more. i dont need a full solution, i will also gladly take hints and links, which will guide me to the right direction. thanks in advance!
I have 2 components, my Navbar and my NavbarButton. the outcome i want is the following: if there is a session show the logout button, if there is no session dont show anything.
right now if i login into my application i have 2 solutions i am not happy with.
- serverside-component: if i make the navbar a serverside component button does not show after a successful login until i refresh the page
- clientside-component: if i make the navbar a client side component the button does show immediately and i dont need to refresh the page but every time i refresh the button disappears for a short time
I will put the code for the server- and clientside navbar and my navbar button in the next messages. I am not sure, if this is all the code you need but if not i will gladly provide you with more. i dont need a full solution, i will also gladly take hints and links, which will guide me to the right direction. thanks in advance!
Answered by Ray
yes because of router cache, so your NavbarButton not rerender after you signin, you have to use
https://nextjs.org/docs/app/building-your-application/caching#invalidation-1
router.refresh to invalidate the router cachehttps://nextjs.org/docs/app/building-your-application/caching#invalidation-1
19 Replies
Large garden bumble beeOP
NavbarButton.tsx (serverside)
//'use client'
import Link from "next/link"
import Image from "next/image"
import styles from './Navbar.module.css'
import NavbarButton from "./NavbarButton"
import { getServerSession } from "next-auth"
import { signOut, /*useSession*/ } from "next-auth/react"
export default async function Navbar() {
const session = await getServerSession()
// const { data: session } = useSession()
return (
<div className={styles.container}>
<Link href="/">
<Image
priority={true}
width={125}
height={40}
className="logo"
src="/logo_torquoise.png"
alt="logo"
></Image>
</Link>
<NavbarButton session={session}/>
</div>
)
}NavbarButton.tsx (clientside)
'use client'
import Link from "next/link"
import Image from "next/image"
import styles from './Navbar.module.css'
import NavbarButton from "./NavbarButton"
// import { getServerSession } from "next-auth"
import { signOut, useSession } from "next-auth/react"
export default function Navbar() {
// const session = await getServerSession()
const { data: session } = useSession()
return (
<div className={styles.container}>
<Link href="/">
<Image
priority={true}
width={125}
height={40}
className="logo"
src="/logo_torquoise.png"
alt="logo"
></Image>
</Link>
<NavbarButton session={session}/>
</div>
)
}NavbarButton.tsx:
'use client'
import { signOut } from "next-auth/react"
import styles from './Navbar.module.css'
import Link from "next/link"
export default function NavbarButton({session}: any) {
return (
<>
{session ? (
<Link href={ "/" }>
<button className={styles.logoutButton} onClick={() => signOut()}>Logout</button>
</Link>
) : null}
</>
)
}Large garden bumble beeOP
you mean client component right? when using it on server component like this
i get the error
and when i use it like this:
i get the error
import { redirect, useRouter } from 'next/navigation';
const router = await useRouter()
router.refresh()i get the error
useRouter only works in Client Componentsand when i use it like this:
import { useRouter } from 'next/router';
const router = await useRouter()
router.refresh()i get the error
Property 'refresh' does not exist on type 'NextRouter'.yes after you run the signin function
and does the
NavbarButton.tsx (serverside) button show if you run router.refresh() after the login function?Large garden bumble beeOP
it seems like i broke my code some time ago. i will answer when i get it to work again
Large garden bumble beeOP
thanks a lot i the router.refresh after the signIn function worked.
LoginForm.tsx
page.tsx (for login)
not sure if this is the prettiest way but it works. i changed the
LoginForm.tsx
const res = await signIn("credentials", {
redirect: false,
username: formValues.username,
password: formValues.password,
callbackUrl,
});
setLoading(false);
if (!res?.error) {
router.refresh() //changed redirect to this
} else {
setError("invalid username or password");
}page.tsx (for login)
export default async function LoginPage() {
const session = await getServerSession(options)
if (session) {
redirect("/")
}
return (
<div className={styles.page}>
<LoginForm />
</div>
)
}not sure if this is the prettiest way but it works. i changed the
redirect('/') after the signin function to router.refresh() and on my login site i check if the user is already logged in and if so i redirect the user to /yes because of router cache, so your NavbarButton not rerender after you signin, you have to use
https://nextjs.org/docs/app/building-your-application/caching#invalidation-1
router.refresh to invalidate the router cachehttps://nextjs.org/docs/app/building-your-application/caching#invalidation-1
Answer
@Large garden bumble bee NavbarButton.tsx:
ts
'use client'
import { signOut } from "next-auth/react"
import styles from './Navbar.module.css'
import Link from "next/link"
export default function NavbarButton({session}: any) {
return (
<>
{session ? (
<Link href={ "/" }>
<button className={styles.logoutButton} onClick={() => signOut()}>Logout</button>
</Link>
) : null}
</>
)
}
Asian black bear
Exactly I did the same thing but my problem is different and looking for answers.
https://nextjs-forum.com/post/1186312453009702952
https://nextjs-forum.com/post/1186312453009702952
Asian black bear
Yes I was thinking about it but I read somewhere router.refresh leads unexpected behavior.
Asian black bear
I don't know where I read it. I have to check history page.
BTW, what do you recommend to use when user sign out, push or replace ? I'm confuse about it.
I think both are fine but I would use replace
Asian black bear
Thanks.