steve123
steve123

Reputation: 385

nextjs layout hydration error hydration failed

I have my main page at /, and I want it to have a different layout than the rest of my app.

The problem is, I have some CSS that applies to the HTML element itself. I tried adding it to the div wrapping page.tsx or applying it to main/body, but for some reason, it’s not working.

Here’s my root layout at src/app:

import { Rubik } from 'next/font/google';
import { ReactNode } from 'react';
import Providers from './Providers';
import { Toaster } from 'sonner';
import './globals.css';

const rubik = Rubik({
  weight: '500',
  subsets: ['latin'],
});

export default async function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html className={`${rubik.className} bg-[#f3f4f6]`} lang="he-IL" dir="rtl">
      <link rel="icon" href="/favicon.ico" sizes="any" />
      <Providers>
        <body>
          <main>{children}</main>
          <Toaster richColors closeButton />
        </body>
      </Providers>
    </html>
  );
}

And here’s the layout for the / route (the main page) at src/app/(root)/layout.tsx (alongside page.tsx in the same route folder):

import { Rubik } from 'next/font/google';
import { ReactNode } from 'react';
import '../globals.css';
import { Toaster } from '@/components/ui/sonner';
import Providers from '../Providers';

const rubik = Rubik({
  weight: '500',
  subsets: ['latin'],
});

export default async function HomeLayout({ children }: { children: ReactNode }) {
  return (
    <html
      className={`${rubik.className} bg-background2 text-[66.6%]`}
      lang="he-IL"
      dir="rtl"
    >
      <link rel="icon" href="/favicon.ico" sizes="any" />
      <Providers>
        <body>
          <main>{children}</main>
          <Toaster richColors closeButton />
        </body>
      </Providers>
    </html>
  );
}

I'm encountering a hydration error, and the UI doesn’t render properly. The issue is that it initializes with the RootLayout, but then the HTML element changes, which causes the font-size to switch to 66.6%, triggering a rerender and messing up the layout.

Any ideas on how to resolve this?

Upvotes: 0

Views: 224

Answers (1)

vzsoares
vzsoares

Reputation: 886

You should have only one root layout. Or one per segment. But never one in the root and one in the segment.

From the docs:

Creating multiple root layouts

To create multiple root layouts, remove the top-level layout.js file, and add a layout.js file inside each route group. This is useful for partitioning an application into sections that have a completely different UI or experience. The and tags need to be added to each root layout.

My suggestion is that you transform the /(root)/layout into a nested layout by removing the tags html and body.

Upvotes: 0

Related Questions