Next.js Discord

Discord Forum

Layout hydration error

Answered
TK-ed posted this in #help-forum
Open in Discord
Avatar
I want to create a separate layout for all of my pages which comes under /dashboard and other one common for any other pages. So i tried using route-groups and it kinda works but im getting hydration error. How do i solve this??
Image
Answered by Siberian
no, layoutts wrap each other
View full answer

59 Replies

Avatar
Siberian
what's the hydration error you're getting?
Avatar
Expected server HTML to contain a matching <main> in <div>.
this comes whenever i wrap something wrong right?? but ive finished building the pages and i cant change it now
is there any other way??
Avatar
Siberian
can you try opening the page without any browser extensions
if you have any
lastpass is a common culprit but probably not the issue here
also this only started happening after adding the layout? And it happens for specific routes under there?
Avatar
import { fontSans } from "@/config/fonts";
import clsx from "clsx";

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html suppressHydrationWarning lang="en">
      <head />
      <body
        className={clsx(
          "min-h-screen bg-background font-sans antialiased light",
          fontSans.variable
        )}
      >
        <div className="relative flex flex-col h-screen">
          <main className="container flex-grow w-full max-w-full px-6">
            {children}
          </main>
        </div>
      </body>
    </html>
  );
}


this is dashboard layout

<html suppressHydrationWarning lang="en">
      <head />
      <body
        className={clsx(
          "min-h-screen bg-background font-sans antialiased light",
          fontSans.variable
        )}
      >
        <Providers themeProps={{ attribute: "class", defaultTheme: "light" }}>
          <div className="relative flex flex-col h-screen max-w-full">
            <main className="container flex-grow px-6 mx-auto">
              {children}
            </main>
          </div>
        </Providers>
        <ToasterSuccess />
      </body>
    </html>


this is the main layout
yupp
Avatar
Siberian
wait but this is the root layout and the one under (dashboard)?
wouldn't those both be rendered?
cause then you have 2 html, body etc tags
Avatar
wait i created a separate layout doesnt that mean itll use that one??
Avatar
Siberian
if you want 2 separate ones you'd need

(root)
-layout.tsx
(dashboard)
-layout.tsx
layout.tsx
in the one at the very root of your project (as in base folder, not inside of (root) ) you'd put your html and body tags
and wrap with providers
folder names obviously also don't matter here
as in you can change root to whatever makes more sense to you
Avatar
hmm im not following
Avatar
Siberian
no, layoutts wrap each other
Answer
Avatar
ohhh sheeet
Avatar
Siberian
if you have

layout.tsx
route1:
-layout.tsx
-nestedroute2:
--layout.tsx
all 3 layouts will be rendered if you go to /route1/nestedrouted2
Avatar
they wrap eaach other but their children dont?? even if thats the case how can i change separate layouts
Avatar
Siberian
children is just a react prop, the layout 1 level down becomes the child, and that has children and so on
when you do

<div>
<Component/>
</div>
Component is {children} to the div
Avatar
i get these
maybe i get hydration due to my contents inside of my children?
Avatar
Siberian
I'm pretty sure it's happening because you have multiple html tags
that's not valid html
use the inspector in your browser to verify
it could be something else causing this but unless I'm missing smth you do have a html tag wrapping another html tag and you should fix that anyway
Avatar
okayy wait lemme check
Avatar
I think we are confused by the fact you return <html> content from dashboard which is very unusual. The layout that return <html> tag is app/layout.tsx by convention

I don't personally know how a mix of <html> tag (which is not a valid syntax) is behaving with the browser (it will try to remove errors) and react (it want to get the same content in browser than in the server)
Avatar
Siberian
I'm guessing React uses the html tag to detect the root of the DOM tree and gets confused when diffing DOMs while trying to hydrate
Avatar
i dont find anything like that
Avatar
Siberian
what does the html look like in your browser inspector
are there multiple <html> tags
Avatar
nope
Avatar
Siberian
which page are you navigating to? Can you put a console.log in both layouts to see if they're both being rendered?
cause they should be
Avatar
yeahh
if i navigate to /dashboard its layout renders and then comes the root layout
Avatar
Siberian
so both the base layout and (dashboard)/layout render?
cause yes that's expected
Avatar
yeahh
Avatar
Siberian
but again, you should nto have your html tags etc there
Avatar
but then even if i dont it makes an issue
https://www.youtube.com/watch?v=LfJlhHnW3I8
this guy does it but for me it doesnt
if i wrap my content (dashboard one) inside of a body tag it works as i want it to be but i get a hydration error
Avatar
Siberian
if you want a separate layout for everything but dashboard, and want dashboard to be a route group you'd do

(dashboard)
-layout.tsx
.....

(root)
-layout.tsx
.....
layout.tsx

where the base level layout.tsx just has html, body and children
I'd suggest you read the docs on layouts and route groups
if you want to visualise what's happening right now put a random div with a label on every layout
and you can see where they "start"
Avatar
now i understand the need for 3 layouts.. and it worked man thanks.
i learned quite a few things from yall
Avatar
Siberian
Happy to help 🙂
Also mark it as a solution with the bot I guess
Avatar
i was going forward with this config and suddenly my svg stopped working
any ideas?? it works with other pages (moreover it just takes em from the public folder right??)
in nested routes they arent working
/dashboard it works
/dashboard/xyz it doesnt