Site icon FSIBLOG

How to Fix React Hydration Error in Next.js

How to Fix React Hydration Error in Next.js

How to Fix React Hydration Error in Next.js

React hydration errors in Next.js can be frustrating especially when you are building a blog page using the WordPress REST API and rendering HTML content like excerpt.rendered.

If you’re seeing errors like:

don’t worry. This guide explains why it happens and provides a complete working fix for WordPress + Next.js.

What is a Hydration Error in Next.js?

Next.js renders your page in two steps:

  1. Server-Side Rendering (SSR): HTML is generated on the server.
  2. Client Hydration: React runs in the browser and attaches event handlers to the existing HTML.

A hydration error happens when:

The server renders one HTML structure
But the browser React render produces something slightly different

Even one small difference like an extra <p>, whitespace, or a different tag structure can trigger hydration problems.

Why This Happens with WordPress REST API Content

WordPress often returns HTML inside fields such as:

Example excerpt coming from WP API:

<p>If you have heard that there are ways to make money while shopping in the UAE and would like...</p>

When you render that using certain parsing methods (like react-html-parser), the server output may differ from the client output.

Common Causes of Hydration Error in Your Setup

Using react-html-parser in SSR:

Libraries like react-html-parser can produce different results in Node.js (server) vs browser (client), causing mismatched markup.

Invalid HTML nesting:

Your code wraps HTML output inside <p className="expert"> ... </p> but WordPress excerpt already contains <p> tags.

That creates invalid HTML like:

<p class="expert">
<p>WordPress paragraph here</p>
</p>

Browsers “fix” invalid HTML differently than React expects → hydration mismatch.

Using unstable keys (key={i}):

Using index keys can cause React to mismatch elements if data order changes or updates between renders.

Your Original Code (Problem Area)

This line causes the biggest issue:

<p className="expert">{ReactHtmlParser(x.excerpt.rendered)}</p>

Because x.excerpt.rendered already contains <p>...</p> tags.

The Best Fix (Recommended for Next.js + WordPress)

Replace react-html-parser with dangerouslySetInnerHTML

This renders the same HTML string on both server and client, preventing hydration mismatches.

Also: Don’t wrap WP HTML inside <p>

Use a <div> instead.

Final Fixed Code (Complete Working Solution)

import React, { Component } from "react";
import Link from "next/link";
import { BiCalendar } from "react-icons/bi";export default class Blog extends Component {
constructor(props) {
super(props);
this.state = {
data: props.bloglist || [],
};
} render() {
const { data } = this.state;
if (!data || data.length === 0) return null; return (
<div className="container blog-section">
<div className="row">
<h2>Latest Posts</h2>
</div> <div className="row">
{data.map((x) => (
<div className="col-md-4 boxs text-center" key={x.id}>
<div className="bg-info">
<img
src={x?.images?.large}
className="img-fluid"
alt={x?.title?.rendered || "Post image"}
/> <h3>{x?.title?.rendered}</h3> <p className="shopping">
<span>
<BiCalendar /> {x?.date}
</span>
</p> {/* FIX: Render WordPress HTML safely without parsing mismatch */}
<div
className="expert"
dangerouslySetInnerHTML={{ __html: x?.excerpt?.rendered || "" }}
/> <Link href={`/blog/${x.slug}/${x.id}`}>
<div className="readmore">
<span>Readmore</span>
</div>
</Link>
</div>
</div>
))}
</div>
</div>
);
}
}

Why This Fix Works

dangerouslySetInnerHTML renders the same HTML string on the server and client
avoids SSR vs browser parsing differences
no invalid nested <p> tags
stable React keys (key={x.id})

Bonus: Make It More Secure (Highly Recommended)

Because WordPress content can contain unwanted HTML, you should sanitize it.

A common option is sanitize-html.

Install:

npm install sanitize-html

Use:

import sanitizeHtml from "sanitize-html";const cleanHTML = sanitizeHtml(x?.excerpt?.rendered || "", {
allowedTags: sanitizeHtml.defaults.allowedTags,
allowedAttributes: {
a: ["href", "target", "rel"],
img: ["src", "alt"],
},
});

Then:

<div dangerouslySetInnerHTML={{ __html: cleanHTML }} />

Conclusion

If you’re using WordPress REST API in Next.js and rendering excerpt.rendered, hydration errors usually come from invalid HTML nesting and differences between server and client parsing.

Exit mobile version