Skip to content

Commit 623b4cb

Browse files
fix(navbar): avoid hydration errors on ISR by deferring auth UI until the session resolves. This guards server-rendered markup against client session loading to maintain consistent UI.
🤖 Generated with Codebuff Co-Authored-By: Codebuff <[email protected]>
1 parent 8b63261 commit 623b4cb

File tree

1 file changed

+38
-27
lines changed

1 file changed

+38
-27
lines changed

web/src/components/navbar/navbar.tsx

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
1+
'use client'
2+
13
import {
24
Menu,
35
DollarSign,
46
LogIn,
57
BarChart2,
68
BookHeart,
7-
User,
89
Bot,
910
} from 'lucide-react'
1011
import Image from 'next/image'
1112
import Link from 'next/link'
12-
import { getServerSession } from 'next-auth'
13+
import { useSession } from 'next-auth/react'
14+
15+
import { cn } from '@/lib/utils'
1316

1417
import { UserDropdown } from './user-dropdown'
18+
import { Icons } from '../icons'
1519
import { Button } from '../ui/button'
1620
import {
1721
DropdownMenu,
1822
DropdownMenuContent,
1923
DropdownMenuItem,
2024
DropdownMenuTrigger,
2125
} from '../ui/dropdown-menu'
22-
import { Icons } from '../icons'
2326

24-
import { authOptions } from '@/app/api/auth/[...nextauth]/auth-options'
25-
import { cn } from '@/lib/utils'
27+
export const Navbar = () => {
28+
const { data: session, status } = useSession()
2629

27-
export const Navbar = async () => {
28-
const session = await getServerSession(authOptions)
30+
// Don't render auth-dependent content during loading to prevent hydration mismatch
31+
const isSessionReady = status !== 'loading'
2932

3033
return (
3134
<header className="container mx-auto p-4 flex justify-between items-center relative z-10">
@@ -72,7 +75,8 @@ export const Navbar = async () => {
7275
Agent Store
7376
</Link>
7477

75-
{session && (
78+
{/* Only show Usage link when session is ready and user is authenticated */}
79+
{isSessionReady && session && (
7680
<Link
7781
href="/usage"
7882
className="hover:text-blue-400 transition-colors font-medium px-2 py-1 rounded-md hover:bg-blue-50 dark:hover:bg-blue-900/20"
@@ -120,15 +124,16 @@ export const Navbar = async () => {
120124
</Link>
121125
</DropdownMenuItem>
122126

123-
{session && (
127+
{/* Only show Usage and Login links when session is ready */}
128+
{isSessionReady && session && (
124129
<DropdownMenuItem asChild>
125130
<Link href="/usage" className="flex items-center">
126131
<BarChart2 className="mr-2 h-4 w-4" />
127132
Usage
128133
</Link>
129134
</DropdownMenuItem>
130135
)}
131-
{!session && (
136+
{isSessionReady && !session && (
132137
<DropdownMenuItem asChild>
133138
<Link href="/login" className="flex items-center">
134139
<LogIn className="mr-2 h-4 w-4" />
@@ -138,24 +143,30 @@ export const Navbar = async () => {
138143
)}
139144
</DropdownMenuContent>
140145
</DropdownMenu>
141-
{session ? (
142-
<UserDropdown session={session} />
143-
) : (
144-
<Link href="/login" className="hidden md:inline-block relative group">
145-
<div className="absolute inset-0 bg-[rgb(255,110,11)] translate-x-0.5 -translate-y-0.5" />
146-
<Button
147-
className={cn(
148-
'relative',
149-
'bg-white text-black hover:bg-white',
150-
'border border-white/50',
151-
'transition-all duration-300',
152-
'group-hover:-translate-x-0.5 group-hover:translate-y-0.5'
153-
)}
146+
147+
{/* Authentication section - only render when session is ready */}
148+
{isSessionReady &&
149+
(session ? (
150+
<UserDropdown session={session} />
151+
) : (
152+
<Link
153+
href="/login"
154+
className="hidden md:inline-block relative group"
154155
>
155-
Log in
156-
</Button>
157-
</Link>
158-
)}
156+
<div className="absolute inset-0 bg-[rgb(255,110,11)] translate-x-0.5 -translate-y-0.5" />
157+
<Button
158+
className={cn(
159+
'relative',
160+
'bg-white text-black hover:bg-white',
161+
'border border-white/50',
162+
'transition-all duration-300',
163+
'group-hover:-translate-x-0.5 group-hover:translate-y-0.5'
164+
)}
165+
>
166+
Log in
167+
</Button>
168+
</Link>
169+
))}
159170
{/* <ThemeSwitcher /> */}
160171
</div>
161172
</header>

0 commit comments

Comments
 (0)