Fix "Hydration failed because the initial UI does not match what was rendered on the server" in NextJS
Haikel, 3 min read / June 5, 2022
بِسْمِ اللَّهِ الرَّحْمَٰنِ الرَّحِيمِ
Note: if you found some bad grammar in this post, i'm sorry. This is my first post in english, so yeah, let me improve my English skill.
So, recently i work on personal project with NextJS. And in development, i got an error like this:
Hydration failed because the initial UI does not match what was rendered on the server
At first, i search the solution in StackOverflow, someone say that <div></div>
tag in <p></p>
tag is the problem. Like this:
<p>
<div>Something</div>
</p>
But when i check my code, there is nothing wrong, Although if i open my console, there was an error like that.
And finally, after a while, i found the solution. I write this because if i'm facing same issue like this, i just open my blog and see this post. For more detail, see the discussion here
Solving Problem
This problem appear when i add progress bar, so i check my _app.tsx
.
import { ThemeProvider } from "next-themes";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { DefaultSeo } from "next-seo";
import type { AppProps } from "next/app";
import "@/src/styles/globals.css";
import "@/src/styles/progress.css";
import Layout from "@/src/components/layout";
import NProgress from "nprogress";
import SEO from "next-seo.config";
function MyApp({ Component, pageProps }: AppProps) {
const router = useRouter();
useEffect(() => {
const handleStart = () => {
NProgress.start();
};
const handleStop = () => {
NProgress.done();
};
router.events.on("routeChangeStart", handleStart);
router.events.on("routeChangeComplete", handleStop);
router.events.on("routeChangeError", handleStop);
return () => {
router.events.off("routeChangeStart", handleStart);
router.events.off("routeChangeComplete", handleStop);
router.events.off("routeChangeError", handleStop);
};
}, [router]);
return (
<ThemeProvider attribute="class">
<DefaultSeo {...SEO} />
<Layout>
<Component {...pageProps} />
</Layout>
</ThemeProvider>
);
}
export default MyApp;
Based on the picture above, in myApp
function, i can add code like this:
function MyApp({ Component, pageProps }: AppProps) {
const [mounted, setMounted] = useState(false); // set to false
const router = useRouter();
useEffect(() => {
setMounted(true); // set to true
const handleStart = () => {
NProgress.start();
};
const handleStop = () => {
NProgress.done();
};
router.events.on("routeChangeStart", handleStart);
router.events.on("routeChangeComplete", handleStop);
router.events.on("routeChangeError", handleStop);
return () => {
router.events.off("routeChangeStart", handleStart);
router.events.off("routeChangeComplete", handleStop);
router.events.off("routeChangeError", handleStop);
};
}, [router]);
return (
mounted && (
<ThemeProvider attribute="class">
<DefaultSeo {...SEO} />
<Layout>
<Component {...pageProps} />
</Layout>
</ThemeProvider>
)
);
}
Done. but new problem appears
Not really important(i think). Because i use my Github profile for icon, i dont add favicon.
Yup, missing favicon.
The solution is: Just create your favicon.ico, and place it in public
folder.