Layout hydration error
Answered
TK-ed posted this in #help-forum
TK-edOP
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??
59 Replies
Siberian
what's the hydration error you're getting?
TK-edOP
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??
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?
TK-edOP
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
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
TK-edOP
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
(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
TK-edOP
hmm im not following
Siberian
no, layoutts wrap each other
Answer
TK-edOP
ohhh sheeet
Siberian
if you have
layout.tsx
route1:
-layout.tsx
-nestedroute2:
--layout.tsx
layout.tsx
route1:
-layout.tsx
-nestedroute2:
--layout.tsx
all 3 layouts will be rendered if you go to /route1/nestedrouted2
TK-edOP
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>
<div>
<Component/>
</div>
Component is {children} to the div
TK-edOP
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
TK-edOP
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)
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
TK-edOP
i dont find anything like that
Siberian
what does the html look like in your browser inspector
are there multiple <html> tags
TK-edOP
nope
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
TK-edOP
yeahh
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
TK-edOP
yeahh
Siberian
but again, you should nto have your html tags etc there
TK-edOP
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
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
(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"
TK-edOP
now i understand the need for 3 layouts.. and it worked man thanks.
i learned quite a few things from yall
i learned quite a few things from yall
Siberian
Happy to help 🙂
Also mark it as a solution with the bot I guess
TK-edOP
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??)
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
/dashboard it works
/dashboard/xyz it doesnt