224

I'm trying to get SSR working in my app but I get the error:

Hydration failed because the initial UI does not match what was rendered on the server.

Live demo code is here

Live demo of problem is here (open dev tools console to see the errors):

// App.js

 import React from "react";
    
  class App extends React.Component {

  head() {
    return (
      <head>
        <meta charSet="utf-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no"
        />
        <meta name="theme-color" content="#000000" />
        <title>React App</title>
      </head>
    );
  }

  body() {
    return (
      <body>
        <div className="App">
          <h1>Client says Hello World</h1>
        </div>
      </body>
    );
  }

  render() {
    return (
      <React.Fragment>
        {this.head()}
        {this.body()}
      </React.Fragment>
    )
  }
}
export default App;

// index.js

import React from "react";
import * as ReactDOM from "react-dom/client";
import { StrictMode } from "react";

import App from "./App";


// const container = document.getElementById("root");
const container = document.getElementsByTagName("html")[0]

ReactDOM.hydrateRoot(
  container,
  <StrictMode>
    <App />
  </StrictMode>
);

The Html template shown in the live demo is served by the backend and generated using the following code:

const ReactDOMServer = require('react-dom/server');

const clientHtml = ReactDOMServer.renderToString(
<StrictMode>
    <App />
</StrictMode>
)

// serve clientHtml to client

I need to dynamically generate <head></head> and <body></body> section as shown in the App class

shankar upadhyay
  • 883
  • 12
  • 18
auser
  • 6,307
  • 13
  • 41
  • 63

55 Answers55

326

I have been experiencing the same problem lately with NextJS and i am not sure if my observations are applicable to other libraries.

I had been wrapping my components with an improper tag that is, NextJS is not comfortable having a p tag wrapping your divs, sections etc so it will yell "Hydration failed because the initial UI does not match what was rendered on the server".

So I solved this problem by examining how my elements were wrapping each other. With material UI you would need to be cautious for example if you use a Typography component as a wrapper, the default value of the component prop is "p" so you will experience the error if you don't change the component value to something semantic.

So in my own opinion based on my personal experience the problem is caused by improper arrangement of html elements and to solve the problem in the context of NextJS one will have to reevaluate how they are arranging their html element.

import Image from 'next/image'
/**
 * This might give that error
 */
export const IncorrectComponent = ()=>{
  return(
    <p>
      <div>This is not correct and should never be done because the p tag has been abused</div>
      <Image src='/vercel.svg' alt='' width='30' height='30'/>
    </p>
  )
}

/**
 * This will work
 */
export const CorrectComponent = ()=>{
  return(
    <div>
      <div>This is correct and should work because a div is really good for this task.</div>
      <Image src='/vercel.svg' alt='' width='30' height='30'/>
    </div>
  )
}
idmean
  • 14,540
  • 9
  • 54
  • 83
Motsi
  • 3,284
  • 1
  • 3
  • 5
  • 3
    This comment on React's Github sums up the issue nicely https://github.com/facebook/react/issues/24519#issuecomment-1122780621. – rantao Sep 17 '22 at 01:08
  • In my case, I had a `Text` component which put its `children` inside an `Elem` which apparently was a `

    ` by default. Hydration failed when the `children` was dangerously set inner HTML . Got rid of the component, and it works fine now. (I could have changed the component config to use a different element. But I realized I didn't need the component there.)

    – ADTC Nov 02 '22 at 12:34
  • Thank you! In my example, I used tr inside the table, when I wrap my tr tags with body it's solved. Wrong path table>tr | Success path table > tbody > tr – Olcay Nov 06 '22 at 17:07
  • The problem with my code was that I put an Image Tag inside a Link Tag. – Tankiso Thebe Nov 17 '22 at 22:23
  • In my case I had a Link wrapping a div and inside the div a button with href attribute was causing the issue. – andychukse Dec 06 '22 at 12:38
  • Thanks for this I had the same problem caused by a `div` rendered into a `button`, turning the former into a `span` solved the issue – kuus Jan 05 '23 at 10:57
  • In my case, I had a button inside a button because of a third-party lib – Kraken Jan 22 '23 at 16:27
  • In my case I had wrapped a div with Next.js `````` component – herbie Feb 26 '23 at 02:30
  • Wow, in my case it wasn't even MY code. I had a Chrome Extension for downloading images in 1 click, and it was introducing an invalid tag in all my images, so SSR failed. – Diego Milán May 26 '23 at 19:04
  • Ese componente Typography me tiene hasta las pelotas siempre da problemas. – Brayan Loayza Jul 12 '23 at 20:28
  • I had a missing `` inside the ``around some ``.
    – alexander Jul 17 '23 at 15:23
62

Importing and running some of the packages can cause this error too. For example, when I used Swiper.js package I encountered this problem. It's mostly because the package is using Window object somewhere.

Since it isn't a good practice to modify the content of the package itself, the best way to tackle such issues is to render the component only after the DOM is loaded. So you can try this.

const Index = () => {
  const [domLoaded, setDomLoaded] = useState(false);

  useEffect(() => {
    setDomLoaded(true);
  }, []);

  return (
    <>
      {domLoaded && (
        <Swiper>
          <div>Test</div>
        </Swiper>
      )}
    </>
  );
};

export default Index;
Rahul Dev
  • 646
  • 2
  • 3
30

If you're using a table, you probably missed <tbody>

incorrect:

<table>
  <tr>
    <td>a</td>
    <td>b</td>
  </tr>
</table>

correct:

<table>
  <tbody>
    <tr>
      <td>a</td>
      <td>b</td>
    </tr>
  </tbody>
</table>
doğukan
  • 23,073
  • 13
  • 57
  • 69
18

This make the app client-side render, it's work for me:

export default function MyApp({ Component, pageProps }: AppProps) {
  const [showChild, setShowChild] = useState(false);
  useEffect(() => {
    setShowChild(true);
  }, []);

  if (!showChild) {
    return null;
  }

  if (typeof window === 'undefined') {
    return <></>;
  } else {
    return (
      <Provider store={store}>
        <Component {...pageProps} />
      </Provider>
    );
  }
}

I also using NextJS, Redux Toolkit

Minh-Thanh Hoang
  • 542
  • 7
  • 21
14

So let me explain why this error can occur in your NEXT JS application.

There are some tags that you can't use inside another tag. For example you can't use div inside a td tag. You can't use p tag inside a span. The same goes for other tags like table, ul etc.

You need to go to your code and remove all the invalid tags used. In my case, I used an a tag inside span which is invalid.

This is invalid

<span>       
  <a target="_blank" href="https://askhumans.io"> Login </a>
</span>

This is valid.

      
  <a target="_blank" href="https://askhumans.io"> <span>  Login </span> </a>
Sanan Ali
  • 2,349
  • 1
  • 24
  • 34
  • Can you provide some documentation or other citation for this? It would also be helpful if this is indeed the case for there to be a linter or similar that can point out these issues. – maxcountryman Jan 30 '23 at 18:57
  • Comes with trial and error, as not sure which tag isn't working in the beginning. – Smart Coder Mar 13 '23 at 14:55
9

The error is misleading as it's not about hydration but wrongly nested tags. I figured out the conflicting tags by removing html and reloading the page until I found the problem (binary search).

In my case it was caused by <a> within <Link>. I thought next.js requires the <a> within the Link but obviously that's not/no longer the case.

See next.js documentation about <Link> tag

hansaplast
  • 11,007
  • 2
  • 61
  • 75
7

Removing the <p> tag solved my similar problem with NEXTJS..

Light
  • 147
  • 1
  • 4
  • It might not be stupid. In my case, I had a component which put its `children` inside an `Elem` which apparently was a `

    `. Hydration failed when the `children` was dangerously set inner HTML . Got rid of the component, and it works fine now. (I could have changed the component config to use a different element. But I realized I didn't need the component.)

    – ADTC Nov 02 '22 at 12:27
4

I have react 18.2.0 with next 12.2.4 and I fix hydration with this code

import { useEffect, useState } from 'react'
import { Breakpoint, BreakpointProvider } from 'react-socks';
import '../styles/globals.scss'

function MyApp({ Component, pageProps }) {
  const [showChild, setShowChild] = useState(false)

  useEffect(() => {
    setShowChild(true)
  }, [])

  if (!showChild) {
    return null
  }

  return (
    <BreakpointProvider>
      <Component {...pageProps} />
    </BreakpointProvider>
  )
}

export default MyApp
Dhia Djobbi
  • 1,176
  • 2
  • 15
  • 35
  • 10
    Since useEffect only runs in the client, this code effectively prevents server-side rendering from happening at all. That may not be what you want. – Salem Nov 10 '22 at 17:26
3

just go to browser, chrome->three bars button on top right corner->more tools->clear browsing history-> delete cookies.

no more error

  • This does actually work. Sometimes it seems the errors are not actually valid. For me I cleared the local storage on the localhost application I was developing and it fixed the issue. – Rob Evans Aug 23 '23 at 13:45
3

If u use html tags u want to place them in correct way and correct order. in NEXTJS.

ex: If u use table.

-> U must add the tbody tag

<!-- Wrong -->

<table>
  <tr>
    <td>Element</td>
    <td>Element</td>
  </tr>
</table>

<!-- Correct Way -->

<table>
  <tbody> <!-- This is a Must -->
    <tr>
      <td>Element</td>
      <td>Element</td>
    </tr>
  </tbody>
</table>
Bathila Sanvidu
  • 121
  • 1
  • 5
3

i ran this piece of code and the problem went away

import "@/styles/globals.css";
import { useEffect, useState } from "react";

export default function App({ Component, pageProps }) {
  const [showChild, setShowChild] = useState(false);
  useEffect(() => {
    setShowChild(true);
  }, []);
  if (!showChild) {
    return null;
  }
  if (typeof window === "undefined") {
    return <></>;
  } else {
    return <Component {...pageProps} />;
  }
}
2

it will work:

 function MyApp({ Component, pageProps }) {
      const [showing, setShowing] = useState(false);

      useEffect(() => {
        setShowing(true);
      }, []);
    
      if (!showing) {
        return null;
      }
    
      if (typeof window === 'undefined') {
        return <></>;
      } else {
        return (
           <RecoilRoot>
             <MainLayout>
                 <Component {...pageProps} />
              </MainLayout>
           </RecoilRoot>
        );
      }
    }

 export default MyApp;

here I used recoil for state managing.

Saeid Shoja
  • 159
  • 2
  • 8
2

If you're using NextJS and Material UI with emotion as the styling engine, then you may need to check the semantics of your components. You can find hints in the errors logged to the browser console.

Example: adding Box component inside Iconbutton will cause an error

There's no need to create a custom NextJS _document.js file because @emotion/react version 10 and above works with NextJS by default.

2

this issue comes in nextjs because dangerouslySetInnerHTML support only div tag. if you insert with other tag its not work.

 <div dangerouslySetInnerHTML={{__html:data.description}}></div>
MOAZZAM RASOOL
  • 159
  • 1
  • 3
2

in Next v13 and upper you shouldn't use <a> as child inside <Link>. if you use that, you'll get error.

in this case I use that in another way:

const Child = () => <a>hello my friend</a>

const Parent = () => {
 return (
  <Link href="/">
    <Child />
  </Link>
 )  
}
  

here I got this error, and I changed child structure for remove <a> to resolve it.

Alireza Khanamani
  • 311
  • 1
  • 3
  • 5
1

So mine is a NEXT JS app.

I am using the react-use-cart module and it seems it has issues with react @18.0.0.

I am not sure how this is possible but downgrading to react @17.0.2 removed my errors.

Previously I was using react @18.0.0

I simply ran npm uninstall react react-dom and installed versions @17.0.2.

Wahala, everything now works as expected.

Think Digital
  • 129
  • 1
  • 7
  • Hey! no need to downgrade, just reformat the object used from the react-use-cart. To clarify more, the items object should bect Json stringified then json parsed inside another variable and that variable insteead, : /// const { items } = useCart() const [allItems, setallItems] = useState([{}]) useEffect(() => { setallItems(JSON.parse(JSON.stringify(items))) }, [items]) /// And the same goes for the cartTotal number just set it in a useState const and it shall work – Firas SCMP Sep 21 '22 at 06:59
1

I had the same issue when tried to put a div inside Card Text of React-Bootstrap.

The error can be reproduced by:

import type { NextPage } from 'next'
import { Card } from 'react-bootstrap';
...
const testPage : NextPage = () => {
...
return (
...
<Card.Text>
    <div>It's an error</div>
</Card.Text>
...
)}

export default testPage

To fix it, i just removed the html tag.

I think that some react components doesn't accept html tags inside.

Mingut
  • 71
  • 6
1

Make sure to wrap in Suspense the lazy modules you import.

In my case I imported

const Footer = React.lazy(() => import('../Footer/Index'));

but I was using it just like a normal module

<Footer />

I wrapped it in Suspense and the error was gone.

<Suspense fallback={<div>Loading...</div>}>
  <Footer />
</Suspense>

Bottom line

If this error is given to you on the home page, try to comment some of the components you use until you find where the error is coming from.

Gabriel Arghire
  • 1,992
  • 1
  • 21
  • 34
1

In my case, it's an user error in nested list. I forgot adding a ul in li so it was just nested lis.

KuN
  • 1,143
  • 18
  • 23
1

Make sure you dont have next/Link nested, I needed to refactor the code and forgod that I had a next/Link before wrapping the image.

for example

        <CompanyCardStyle className={className}>
            //Open Link
            <Link href={route('companyDetail', { slug: company.slug })}>
                <a className='d-flex align-items-center'> 
                    <div className='company-card'>
                        <div className='d-flex align-items-center col-name-logo'>
                            <div className='company-logo'>
                                //Remove link and let the <a> child
                                <Link href={route('companyDetail', { slug: company.slug })}>
                                    <a><img src={company.logoUrl} width={'100%'} /></a>
                                </Link>
                            </div>
                            <h6 className='mb-0'>{company.name}</h6>
                        </div>
                        .....
                    </div>
                </a>
            </Link>
        </CompanyCardStyle>
skyllet
  • 1,991
  • 2
  • 12
  • 10
1

Hydration failed because the initial UI does not match what was rendered on the server

You should check the console for errors like:

Warning: Expected server HTML to contain a matching <div> in <div>.

and fix them.

Copied from https://github.com/vercel/next.js/discussions/35773

mbappai
  • 557
  • 1
  • 5
  • 22
1

I had this issue when I moved the pages directory in NextJs. I solved it by deleting the .next folder and rebuilding it using yarn build.

kirr kirry
  • 11
  • 1
1

I solved this problem by NextJs dynamic import with ssr: false

import dynamic from 'next/dynamic'
import { Suspense } from 'react'

const DynamicHeader = dynamic(() => import('../components/header'), {
    ssr: false,
})

export default function Home() {
    return (
        <DynamicHeader />
    )
}
lahiru dilshan
  • 690
  • 9
  • 13
1

My case was that I used the table without tr in thead in NextJS.

It was:

<table className="table">
  <thead>
    <th>head</th>
  </thead>
  <tbody>
    <tr>
      <td>content</td>
    </tr>
  </tbody>
</table>

then I added tr inside thead:

<table className="table">
  <thead>
    <tr>
      <th>head</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>content</td>
    </tr>
  </tbody>
</table>

Now the issue is resolved.

holydragon
  • 6,158
  • 6
  • 39
  • 62
1

This is surely a problem related to tags. If you are using NextJS as FE framework, I'd suggest to use 'Box' tag for the component where you are using your child components. It will allow you to use most of the tags successfully inside your child component. For having extra safe, you can use template literals to wrap the child component.

shuhat36
  • 251
  • 2
  • 5
1

This happens due to using server-client-based conditional renders.

Ie: if you use a block based on the existence of window (ie when react hydrates and we're on client side), but it differs in SSR'ed condition, hydration fails as initial UI mismatches server side render (SSR).

typeof window !== 'undefined' ? <div>something</div> : <div> something else</div>

With the above code, you're mismatching server side render with client render, avoid these clauses and use a different approach to your logic to fix this error, ie use useState hook to keep this logic outside the function by setting it initially at componentDidMount stage using useEffect hook with an empty array as second attribute.

sed
  • 5,431
  • 2
  • 24
  • 23
1

This problem happened to me when I tried to render my component as client-side rendering, and it mismatched with hydration. so we can disable hydration during client-side rendering to fix this problem.

The given method below worked for me

import dynamic from 'next/dynamic' 

function Mycomponent(){
   return (
     <h1>Hello world<h1/>
  )
}

export default dynamic(() => Promise.resolve(Mycomponent), { ssr: false });

1

As the solutions above, it is correct that the error itself was not so explanatory, and yes the issue was the tags being misplaced issue.

In my case, I am using NextJS 13.4, and I was trying to show a Navbar component that was separately created, so I wanted to add it to my root Layout. I was applying the Navbar wrong.

Wrong

export default function RootLayout({ children }) {
  return (
    <html lang="en" className={d_script.className}>
      <Navbar />
      <body> {children} </body>
    </html>
  );
}

Correct

export default function RootLayout({ children }) {
  return (
    <html lang="en" className={d_script.className}>
      <body>
        <Navbar />
        {children}
      </body>
    </html>
  );
}

As Navabar is shown within the body, so it should be wrapped within it, and it is also a tag issue so the error 'Hydration failed because the initial UI does not match what was rendered on the server' was shown.

0

I had the same issue with Next.js and Faker.js, and i just use conditional rendering and it's solved. I think it happened because the values from faker.js changes twice when page first loading. Code below may help you.

`

    export default function Story() {
    const [avatar, setAvatar] = useState(null);
    const [name, setName] = useState(null);

    useEffect(() => {
    setAvatar(faker.image.avatar());
    setName(faker.name.findName());
    }, []);

    return (
    <>
      {avatar && name && (
      <div>
        <Image
          src={avatar}
          alt="Story Profile Picture"
          width={50}
          height={50}
      />
        <p>{name}</p>
      </div>
      )}
    </>
   );
}

`

0

You Can wrap your component that cause this error with Nossr from mui(material-ui)

import NoSsr from "@mui/material/NoSsr";

<NoSsr> {your contents} </NoSsr>

to get more info: https://mui.com/material-ui/react-no-ssr/

Mohamad
  • 79
  • 1
  • 2
  • 1
    This is the same as other solutions on this page, it is not tackling the underlying issue, this will only render client side – Joel Davey Dec 27 '22 at 19:54
0

In my case, when I used reverse() function before mapping my list, I was getting a similar error.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 03 '22 at 01:15
0

In my case, neither making the HTML more semantic nor modifying the _app.tsx to check if the window was loaded.

The only solution, for now, was to downgrade the React version and the React DOM.

I'm using NextJS.

I switched to version 17.0.2.

AndresdoSantos
  • 49
  • 1
  • 1
  • 5
0

In my case, I faced this problem because I had used <img /> tag instead of Next.js <Image /> tag because I couldn't use tailwind classes with the <Image /> tag. Replacing the <img /> tag with Next.js <Image /> tag solved the issue for me. Then I wrapped the <Image /> tag with a div tag and added the classes to that.

0

I ran into same issue using NextJS with Material UI. Actual solution is to use NextJS dynamic import. In the example below do not import header component as:

import Header from "../components/header"

Instead do:

import dynamic from 'next/dynamic'

const DynamicHeader = dynamic(() => import('../components/header'), {
  suspense: true,
})

Check the NextJS documentation below:

https://nextjs.org/docs/advanced-features/dynamic-import

Dhia Djobbi
  • 1,176
  • 2
  • 15
  • 35
0

I had this issue even with create-next-app without any changes and tried with a different browsers and profiles. I see that there is no problem with them so I investigated my extensions but it didn't solve the problem. Finally, I've solved it by investigating chrome dev tools settings. My problem is related to "Enable Local Overrides". So I unchecked that and it was solved.

Enable Local Overrides on Chrome Settings

1

Minh-Long Luu
  • 2,393
  • 1
  • 17
  • 39
0

If you're deploying the NextJs app to AWS using PM2. You just have to rebuild and restart your app process.

Codedreamer
  • 1,552
  • 15
  • 13
0

For me the reason was I forgot to wrap <td> element inside <tr> element.

gives you error.

 <thead className="w-full">
      <td className="w-1/12"></td>
      <td className="w-8/12"></td>
      <td></td>
    </thead>

the correct way:

 <thead className="w-full">
      <tr>
        <td className="w-1/12"></td>
        <td className="w-8/12"></td>
        <td></td>
      </tr>
    </thead>
etrafa
  • 1
  • 1
0

For me the issue was caused by date-fns package. After removing the component that was using the date formatting, the error message which was showing up only after deploying went away. Hope this helps.

0

I was getting this same error in NextJs when trying to work using context and localstorage, the problem was solved by doing a check in _app.

  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/33180453) – Lord-JulianXLII Nov 20 '22 at 21:10
0

I had the same issue. If you're using a state management like redux, better to have a boolean state like 'isHydrated' with initial value of 'false'. Once the initial ui is initialized, set it to 'true'. Consume this value in every component with dynamic ui rendering that will possibly encounter with this error.

DO NOT put this state at the component level, this will affect initial rendering as the component will recreate 'isHydrated' with initial value of 'false':

function App(){
  const [isHydrated, setIsHydrated] = useState(false)

  useEffect(() => {
    setIsHydrated(true)
  }, []);

  return (
  <div>
    {isHydrated ? <p>Hello</p> : null}
  </div>
  )
}



function Component(){
  const [isHydrated, setIsHydrated] = useState(false)

  useEffect(() => {
    setIsHydrated(true)
  }, []);

  return (
  <div>
    {isHydrated ? <p>Hello</p> : null}
  </div>
  )
}

INSTEAD, do something like this:

// initialize ui rendering

    function App(){
      const isHydrated = useSelector(s => s.isHydrated)
    
     useEffect(() => {
        dispatch({ type: 'SET_IS_HYDRATED' })
      }, []);
    
      return (
      <div>
        {isHydrated ? <p>Hello</p> : null}
      </div>
      )
    }


// just consume the state at the component level and will render correctly when 
// navigating to other page with 'isHydrated' value of 'true'

    function Component(){
      const isHydrated = useSelector(s => s.isHydrated)
    
      return (
      <div>
        {isHydrated ? <p>Hello</p> : null}
      </div>
      )
    }
0

Just I removed <body> <body/> in body from App.js

import React from 'react';

class App extends React.Component {
  head() {
    return (
      <div>
        <head>
          <meta charSet="utf-8" />
          <meta
            name="viewport"
            content="width=device-width, initial-scale=1, shrink-to-fit=no"
          />
          <meta name="theme-color" content="#000000" />
          <title>React App</title>
        </head>
      </div>
    );
  }

  body() {
    return (
      <>
        <div className="App">
          <h1>Client says Hello World</h1>
        </div>
      </>
    );
  }

  render() {
    return (
      <React.Fragment>
        {this.head()}
        {this.body()}
      </React.Fragment>
    );
  }
}

export default App;

I got success after removing <body> <body/>

0

one more tiny finding from NextJS + Chakra UI, please also ensure NEVER do something like below:

<a href="https://github.com/xxx" target="_blank" rel="noreferrer">
  <IconButton
    as="a"
    href="#"
    aria-label="GitHub"
    icon={<FaGithub fontSize="1.25rem" />}
  />
</a>

This will also trigger the above error: Hydration failed because the initial UI does not match what was rendered on the server

Conclusion: please ensure the code you write is valid and make sense during debugging purpose.

DamonWu
  • 108
  • 3
0

Recently I got a similar error and I realized that it happens when a component has a nested nextjs Link (next/link):

<Link>
...
 <NestedComponenWithAnotherLink />
...
</Link>

=> NextJS 13.1.6

Cheers.

0

This error means that in the html DOM tree there are some semantic issues.

For example: <tbody> has direct children <div> instead of <tr>.

So, improving those issues, we can get right basis for accessibility.

Erik P_yan
  • 608
  • 5
  • 6
0

Tested with Next13.

I had this issue when I forgot to utilize next/script instead of the html script element. This was in the layout.tsx file where I wanted to apply the script on all pages.

In my case, the script was rendering an element, and when routing state changes, this element is not rendered, thus the script wasn't loading and causing the hydration error.

mahmoudafer
  • 1,139
  • 3
  • 14
  • 30
0

According to Vercel's docs, this can be caused by

  1. Incorrect nesting of HTML tags
    1. <p> nested in another <p> tag
    2. <div> nested in a <p> tag
  2. Using checks like typeof window !== 'undefined' in your rendering logic
  3. Using browser-only APIs like window or localStorage in your rendering logic
  4. Browser extensions modifying the HTML
  5. Incorrectly configured CSS-in-JS libraries
  6. Incorrectly configured Edge/CDN that attempts to modify the html response, such as Cloudflare Auto Minify

Solution 1: Using useEffect to run on the client only

Ensure that the component renders the same content server-side as it does during the initial client-side render to prevent a hydration mismatch. You can intentionally render different content on the client with the useEffect hook.

import { useState, useEffect } from 'react'
 
export default function App() {
  const [isClient, setIsClient] = useState(false)
 
  useEffect(() => {
    setIsClient(true)
  }, [])
 
  // return <h1>{isClient ? 'This is never prerendered' : 'Prerendered'}</h1>
  return <div> {isClient && (<ClientComponent/>)} </div>

}

During React hydration, useEffect is called. This means browser APIs like window are available to use without hydration mismatches.

Solution 2: Disabling SSR on specific components

import dynamic from 'next/dynamic'
 
const NoSSR = dynamic(() => import('../components/no-ssr'), { ssr: false })
 
export default function Page() {
  return (
    <div>
      <NoSSR />
    </div>
  )
}

Solution 3: Using suppressHydrationWarning

Sometimes content will inevitably differ between the server and client, such as a timestamp. You can silence the hydration mismatch warning by adding suppressHydrationWarning={true} to the element.

<time datetime="2016-10-25" suppressHydrationWarning />
Ali80
  • 6,333
  • 2
  • 43
  • 33
0
import { useState, useEffect } from 'react'
 
export default function App() {
  const [isClient, setIsClient] = useState(false)
 
  useEffect(() => {
    setIsClient(true)
  }, [])
 
  return isClient ? (<div>Content</div>) : <></>
}

Source: https://nextjs.org/docs/messages/react-hydration-error

WestMountain
  • 136
  • 1
  • 1
  • 8
0

The issue is that initially rendered UI changes after the initial render based on layout size / parent item size detections.

I was rendering a component which requires to use window size. For the initial render my useBreakpoint hook returns null since the window object is undefined.

You can utilize useLayoutEffect to wait for to able to access properties of layout before the initial render.

  const currentBreakpoint = useBreakpoint();

  const [isLayoutReady, setIsLayoutReady] = React.useState(false);

  React.useLayoutEffect(() => {
    setIsLayoutReady(true);
  }, []);

  const itemToShow =
    currentBreakpoint === Breakpoint.xl ? props.item : null;

  return (
   <div>
     {isLayoutReady && itemToShow}
    </div>
  )
Alper Güven
  • 329
  • 4
  • 15
0

Disabling SSR on specific components

Doing ssr:false on importing component as dynamic worked for me. For more details go to NextJs official website here

import dynamic from 'next/dynamic'
 
const NoSSR = dynamic(() => import('../components/no-ssr'), { ssr: false })
 
export default function Page() {
  return (
    <div>
      <NoSSR />
    </div>
  )
}
0

I am using Chakra Ui with Next js, when i removed tag in my error is gone.

ilvcs
  • 103
  • 1
  • 17
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 28 '23 at 21:21
-1

It happened to me in Nextjs and I found out I accidentally moved the index.js file into another folder. So I returned it to the pages folder and all was well.

Meshack
  • 1
  • 3
-1

I just faced the similar error. In my case I was also using Nextjs, basically the problem was that I was not using the tag inside the tag. And usually, browsers automatically adds the if I just place inside the tag, and don't specify the either tbody or thead tag inside the table tag.

I believe this can apply to all other similar HTML tags and it was telling in the error, that something is rendering on the DOM which you've not mentioned in code.

One more thing, I was using the nested loop in that particular section first to map the table rows and then a certain table data field. When I removed the nested map it worked without adding the tbody and also worked when I added the tboday but kept the nested loop. So, I'm not sure why it's weird. However, it's working so f* it.

ivewor
  • 11
  • 1
  • 4
-1

This is working for me to get client side rendering throughout the app. No more worries about using window throughout the rest of the app.

import useSSR from 'use-ssr'

function MyApp(props) {
  const { Component, pageProps } = props

  return (
    <>
      <Head>
        <title>title</title>
        <meta name='description' content='Generated by create next app' />
        <link rel='icon' href='/favicon.ico' />
      </Head>
      <ClientSideRenderedNextJS>
        <Component {...pageProps} />
      </ClientSideRenderedNextJS>
    </>
  )
}

function ClientSideRenderedNextJS({ children }) {
  const [domLoaded, setDomLoaded] = useState(false)
  
  useEffect(() => {
    setDomLoaded(true)
  }, [])

  const { isServer } = useSSR()
  if (!domLoaded) return null
  if (isServer) return <></>

  return children
}
Alex Cory
  • 10,635
  • 10
  • 52
  • 62
-1

This works for me, Nextjs.

export default function MyApp({ Component, pageProps }: AppProps) {
 const [showChild, setShowChild] = useState(false);
useEffect(() => {
setShowChild(true);
}, []);

if (!showChild) {
return null;
}

if (typeof window === 'undefined') {
return <></>;
} else {
 return (
   <Provider client={state}>
     <Component {...pageProps} />
   </Provider>
 );
}

}

-4

I had similar issues. Reverting back to a stable version of react worked the magic

Consider reverting back to React 17

Here is a github discussion (https://github.com/vercel/next.js/discussions/35773)