Fixing React Hydration Mismatch Errors in SSR Web Apps

What is Hydration?

In Server-Side Rendering (SSR), the server generates a static HTML page, which is sent to the client. The browser displays this page instantly, and React “hydrates” it by mapping JavaScript behaviors and events to the static markup. If the server HTML structure doesn’t match client-side React layout, hydration fails.

Case Study: The Jumbled Layout

A marketing site rendered dynamic elements correctly on load, but immediately after hydration, elements shifted around, buttons became unclickable, and the console was filled with warnings stating: Hydration failed: HTML text content did not match server-rendered text.

The Bug: Accessing Client State during Server Render

The developer rendered local timestamps directly using standard formatting:

// Offending component
export default function TimeDisplay() {
    // Server renders UTC time, but client renders local browser time!
    return <div>Current Time: {new Date().toLocaleTimeString()}</div>;
}

The Fix: Post-Mount Rendering

To fix this mismatch, ensure client-specific values are only rendered after the component has mounted on the client:

export default function TimeDisplay() {
    const [time, setTime] = useState("");
    
    useEffect(() => {
        setTime(new Date().toLocaleTimeString());
    }, []);

    // Return a placeholder structure during server rendering
    return <div>Current Time: {time || "Loading..."}</div>;
}
Scroll to Top