1. 17
    Create Shared Nav Bar in Next.js with _app.js
    1m 39s

Create Shared Nav Bar in Next.js with _app.js

Share this video with your friends

Send Tweet

Manually typing the URL to navigate between our different pages is becoming cumbersome. Let's create a shared navigation bar that will display on every page in our application.

In this video, we create a new component to display our Nav options - / and /pricing. Each of our routes uses the Next.js <Link> component to make transitions between pages client-side. By rendering our <Nav> component in pages/_app.js, our navbar will display on every page.

Additionally, we would like to dynamically swap out our login and logout options, based on the user's signed in status. In order to do this, we can use the useUser hook and conditionally render each link based on our user's state.

James
James
~ 3 years ago

I'm running into this console warning: Warning: Text content did not match. Server: "Login" Client: "Logout", everything is Seems to be caused by:

<Link href={user ? '/logout' : '/login'}>
     <a className="ml-auto">{user ? 'Logout' : 'Login'}</a>
</Link>

In the nav component

Martin
Martin
~ 2 years ago

When i login and refresh the start-page i get an hydration error: "Error: Hydration failed because the initial UI does not match what was rendered on the server."

Martin
Martin
~ 2 years ago

@James in user.js initializing our user state with "userState(null)" instead of "userState(superbase.auth.user()) fixes the problem.

After an intense read about hydrating, i think it's because while rendering the page on the server, it cant resolve superbase.auth.user() (because it retrieves the user object from localstorage(?) and the server has no access to localstorage) but on the clients first render, there is a user object, which results in content not matching between server and client.

I hope you get the point

Jon Meyers
Jon Meyers(instructor)
~ 2 years ago

That is exactly the problem! I am working on a revision for the course that fixes this issue, but until then, here is a blog that demonstrates how to switch off SSR for the Navbar component

https://jonmeyers.io/blog/fix-client-server-hydration-error-in-next-js

Melwyn Turbant
Melwyn Turbant
~ 2 years ago

I fixed the hydration error by doing this:

import Link from 'next/link';
import { useUser } from '../context/user';

const Nav = () => {
  const { user, isLoading } = useUser();
  return (
    <nav>
      <Link href="/">
        <a>Home</a>
      </Link>
      <Link href="/pricing">
        <a>Pricing</a>
      </Link>
      {!isLoading && (
        <Link href={user ? '/logout' : '/login'}>
          <a>{user ? 'Logout' : 'Login'}</a>
        </Link>
      )}
    </nav>
  );
};

export default Nav;

If you're wondering where this isLoading is coming from, this is something that is covered in lesson 18 - "Query Dynamic Supabase Data in Static Pages Using Next.js".

isLoading is set to true when UserProvider is loading.

If it's loading then we prevent the login or logout link to show with:

{!isLoading && (
        <Link href={user ? '/logout' : '/login'}>
          <a>{user ? 'Logout' : 'Login'}</a>
        </Link>
      )}