Next.js Discord

Discord Forum

Hydration error when window is used inside client component?

Answered
Black-bellied Whistling-Duck posted this in #help-forum
Open in Discord
Avatar
Black-bellied Whistling-DuckOP
Error msg : Error: Hydration failed because the initial UI does not match what was rendered on the server

'use client'

export default function Navbar({ isLoggedIn }) {
return  isLoggedIn ? null : 
          typeof window !== 'undefined' ? null : 
            <div>
                <a
                  href={`${
                    window.origin + process.env.NEXT_PUBLIC_BASE_PATH
                  }/auth/login?return_to=${window.location}`}
                  className="sign-in-button"
                >
                  Sign in
                </a> 
            </div>
}

So how do I fix this hydration issue?
Answered by Rafael Almeida
you could either:
1. have the app base path as an env variable (like https://app.com) and use it to complete the URL so it works in the server
2. delay the rendering of the link so it only reads from window after it has been mounted. using the useEffect hook
View full answer

7 Replies

Avatar
client components are still rendered on the server (they are basically the same thing as components in the pages dir) so you can't access the window variable like that. you can only run client-side code in places you know won't run in the server, like inside useEffect
as for the code itself, you don't really need all of this. you can just do href="/auth/login and the browser will correctly complete the URL. for the return_to parameter, you can use the usePathname hook to get the current pathname even in the server: https://nextjs.org/docs/app/api-reference/functions/use-pathname
Avatar
Black-bellied Whistling-DuckOP
Thanks for the reply.
But I need entire location in return_to parameter, not just pathname.
How do I construct the entire url?
Avatar
you could either:
1. have the app base path as an env variable (like https://app.com) and use it to complete the URL so it works in the server
2. delay the rendering of the link so it only reads from window after it has been mounted. using the useEffect hook
Answer
Avatar
Black-bellied Whistling-DuckOP
I will go with first method.