javascriptnext.jsnavnext.js13

Next.js layout strange behavior


I have no idea of why that happens, I have a layout with my navbar, but when I refresh the page the navbar blink in the screen and fade away.

My app dir tree:

.
├── actions.tsx
├── api
│   └── test
│       └── route.ts
├── globals.css
├── layout.tsx
└── page.tsx

In layout.tsx:

import "./globals.css";
import { Inter } from "next/font/google";
import Link from "next/link";

const inter = Inter({ subsets: ["latin"] });

export const metadata = {
  title: "Blachere CRM",
  description: "Blachere CRM by Jonathan Lauxen Romano",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  type NavItem = {
    title: string;
    path: string;
  };

  const navigation: NavItem[] = [
    {
      title: "Home",
      path: "/",
    },
    {
      title: "Contacts",
      path: "/contacts",
    },
    {
      title: "Proposals",
      path: "/newProposal",
    },
  ];

  return (
    <html lang="en">
      <nav className="bg-blue-500 text-white h-12 flex items-center justify-center gap-12">
        {navigation.map((navItem) => (
          <Link key={navItem.title} href={navItem.path}>
            <div>{navItem.title}</div>
          </Link>
        ))}
      </nav>

      <body className={inter.className}>{children}</body>
    </html>
  );
}

And in page.tsx:

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <text>test</text>
    </main>
  )
}

After the blink, I got the following errors:

Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.

Error: Hydration failed because the initial UI does not match what was rendered on the server.
Warning: Expected server HTML to contain a matching <nav> in <html>.
See more info here: https://nextjs.org/docs/messages/react-hydration-error

I tried paste the same code on other page(contacts) and works well:

.
├── actions.tsx
├── api
│   └── teste
│       └── route.ts
├── contacts
│   ├── layout.tsx
│   └── page.tsx
├── globals.css
├── layout.tsx
└── page.tsx

So what am I doing wrong? What can I do to fix that?


Solution

  • I suggest a fix HTML Code.

    In layout.tsx:

    <html lang="en">
      <body className={inter.className}>
        <nav className="bg-blue-500 text-white h-12 flex items-center justify-center gap-12">
          {navigation.map((navItem) => (
            <Link key={navItem.title} href={navItem.path}>
              <div>{navItem.title}</div>
            </Link>
          ))}
        </nav>
        {children}
      </body>
    </html>
    

    This is because the code that makes up the 'body' must be entered. This is one of the errors that occur for this reason.