Next.js Discord

Discord Forum

Layout hydration error

Answered
TK-ed posted this in #help-forum
Open in Discord
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??
Answered by Siberian
no, layoutts wrap each other
View full answer

59 Replies

Siberian
what's the hydration error you're getting?
@Siberian what's the hydration error you're getting?
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??
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?
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
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
@Siberian cause then you have 2 html, body etc tags
wait i created a separate layout doesnt that mean itll use that one??
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
hmm im not following
@TK-ed wait i created a separate layout doesnt that mean itll use that one??
Siberian
no, layoutts wrap each other
Answer
@Siberian no, layoutts wrap each other
ohhh sheeet
Siberian
if you have

layout.tsx
route1:
-layout.tsx
-nestedroute2:
--layout.tsx
all 3 layouts will be rendered if you go to /route1/nestedrouted2
@Siberian no, layoutts wrap each other
they wrap eaach other but their children dont?? even if thats the case how can i change separate layouts
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
i get these
maybe i get hydration due to my contents inside of my children?
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
@Siberian use the inspector in your browser to verify
okayy wait lemme check
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)
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
Siberian
what does the html look like in your browser inspector
are there multiple <html> tags
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
if i navigate to /dashboard its layout renders and then comes the root layout
Siberian
so both the base layout and (dashboard)/layout render?
cause yes that's expected
Siberian
but again, you should nto have your html tags etc there
@Siberian but again, you should nto have your html tags etc there
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
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"
Siberian
Happy to help 🙂
Also mark it as a solution with the bot I guess
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