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:

  • Hydration failed because the initial UI does not match what was rendered on the server
  • Text content does not match server-rendered HTML
  • Expected server HTML to contain a matching

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:

  • title.rendered
  • excerpt.rendered
  • content.rendered

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.

author-avatar

About Bruno Naschpitz

Bruno is a visionary senior software engineer and entrepreneur with over 12 years of experience in crafting innovative applications. His expertise spans full-stack development, leveraging Node.js, React, Next.js, and Meteor frameworks to deliver high-performance solutions. With a passion for automated testing, Bruno brings a unique blend of technical excellence and entrepreneurial spirit to his work, driving cutting-edge technology solutions to the forefront.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments