home
Wednesday, June 22, 2022

Hydration failed - React Encoder Error

Sometimes, it’s quite annoying to encounter a hydration failed error in ReactJS but the error is not obvious to figure out. Here are my experiences about how I fixed that error in my web application written by NextJS/ReactJS.

Error description

After adding dark mode support to my website, I deployed it to production and got back these error:

More often, it wouldn’t be difficult to find out the root cause might be that some of my codes had access to DOM while the website was in server-side rendering (SSR) progress. For instance, in my case, there might be a call to window.localstorage to get dark mode preference while the app was in SSR, and the result would be the miss-match HTML rendering between server response and client rendering, just because window object was undefined in server-side.

However, it wasn’t the case for me, I had carefully added a check typeof window === ‘undefined’ before accessing localstorage to make sure the code was run in the browser environment…And it took me quite a while to figure out the root cause of HTML mis-match was in the data that was used to render HTML code in SSR and the data that was sent to the client for rendering.

The error

In my website, I previously sorted articles by alphabet. Then, I changed to sort them by date, and dates were stored as string, so I converted date strings into Date objects (JS), sorted them, serialized them and returned them to client-side - note that NextJS does not serialize Date objects for us by default, this library superjson-next will help to do that. Read this thread to see why NextJS fails to serialize Date objects.

The problem came from how browsers parse date string format into Date objects. For example, in data send to client, I have a date string in ISO format 2022-06-20T00:00:00.000Z, that was date in UTC time, but when my browser parsed that date string, it automatically converted the date into local offset, and for me that was June 19th in Eastern Time.

Date parsing

And here was the mis-match data that caused the hydration error in React-DOM.

Error 418

The fix

Since I just want to display dates and don’t care about time, I updated my code to format date string on server-side, on client-side just simply use that string format for displaying, and there was no datetime converting on client-side anymore.

Lessons Learned

top