Most probably the problem you are facing is not because of your code but because of some Cloudflare service, modifying your code to protect your code! 😅
Yeah! It goes in a full circle (that’s why the image)!
Errors are there to protect you, after all! 😂
Let me shade some light…
I have a Next.js web app hosted on Cloudflare — for simplicity let’s call it example.com
and its Cloudflare pages domain be example.pages.dev
Now the background, I have a paragraph on the home page that includes my email address. Something link in the code snippet below 👇
<p>Contact us at [email protected]</p>
This is ok and it has no problem! It works well on local machines, on preview pages, and even on example.pages.dev
The errors start when we visit our custom domain example.com
👇
Though, let me clarify for me this was not a big issue because it has no effect to my users! But there’s a possibility that a similar issue can have impact for you — Just saying 🥲
Coming back to the issue! All three errors were:
- Text content does not match server-rendered HTML.
- Hydration failed because the initial UI does not match what was rendered on the server.
- There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
I was completely confused about why this was even happening in the first place and only on the custom domain, I spent hours figuring it out, as I was not liking it. I hate console errors!
I checked all the code, and even tried a few things! Restructured a little bit to figure out the issue! No luck. (How could it be the problem was not there)
the solution…
Then I decided to go old school! Something I do when I don’t find the solution. 😶
Now, I decided to compare the actual rendered pages!
- Opened
example.com
in one tab andexample.pages.dev
in another - Right clicked on both of them and clicked
View Page Source
- Copied both of them and beautified them for readability 🥲
- And then diff checked them using https://www.diffchecker.com/
And this is the only difference that I found 👇
Now, it was clear! Cloudflare was protecting the email address but why? 😅
Turns out there’s a service that was enabled called Email Address Obfuscation.
...but what is Email Address Obfuscation..?
Well, what it does actually is that it prevents the bots from scraping email addresses from your websites, by removing the email from the page text and then re-render the DOM element using Javascript, populating the email address again — which was causing the problem for React as the initial text content was not matching the server-rendered HTML.
Bingo! We found the problem 😅
And to solve it either ignore it or make Cloudflare stop obfuscating it:
- Add the following comment in the page HTML code:
<!--email_off-->`_your_email addresses go here_`<!--/email_off-->
- Return email addresses in JSON format for AJAX calls, making sure your web server returns a content type of
application/json
. - Disable the Email Obfuscation feature by creating a Configuration Rule or Page Rule to be applied on a specific endpoint.
Now, you know how to solve the problem.
Conclusion
Now, what did I learn from the incident is that always look for the post-processors first! They can be the reason for your problems and will save you a lot of your time.
And if you are using Cloudflare, there are a lot and lots of them!
But Thank you, Cloudflare for being such a useful pain in the ***! 😂
If this was helpful, I document a lot of such learnings and experiences on Twitter, you can follow me there – @010Shivam!
Thanks for reading! Enjoy your day! 😉
Originally, posted on Medium@Shivam010 on July 14th 2023