Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

isomorphic/universally-rendered React 15 app breaks with Cloudflare HTTP Proxy ("orange cloud")

I have an isomorphic/universal React app, meaning it is rendered on the server by the same JS that powers the client-side, Single Page App user experience.

I configure this app's DNS using Cloudflare, and use their "orange cloud" feature to accelerate and protect my site's traffic, as explained in the following graphic and in their support article:

Orange Cloud: Records that display an orange cloud icon are accelerated and protected by Cloudflare. Grey Cloud: Records that display a grey cloud icon will bypass Cloudflare, using only Cloudflare DNS

From the linked-to article: "Cloudflare can operate in two modes - DNS only (unproxied; 'grey cloud') and as a HTTP proxy ('orange cloud') with our security, CDN & performance features."

I have discovered that running my app with React 15 and Cloudflare's "orange cloud" HTTP Proxy feature results in an error:

reactProdInvariant.js:31 Uncaught Error: Minified React error #32; visit http://facebook.github.io/react/docs/error-decoder.html?invariant=32&args[]=2 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

The text of the linked-to bug:

Unable to find element with ID 2.

This ID probably refers to the head tag of my page:

<!doctype html>
<html lang="en-us" data-reactroot="" data-reactid="1" data-react-checksum="-1233854461"><head data-reactid="2">...

I do NOT get this issue with React 14.

I do NOT get this bug when using the raw, un-DNS-ed address of my app, nor do I get it when I switch to the "grey cloud" to use Cloudflare as only a DNS service.

I do NOT get this issue when I disable server-side rendering.


When I google the text of the linked-to "actual" error, I find this Github thread that confirms that this has something to do with server-side rendering.

However, my situation differs slightly: that thread's author encounters the error with an "unable to find element" ID referring to a style tag, whereas in my case the unfound element ID refers to the head tag.


When I google the text of the production "wrapped" error, I find this Github thread that confirms that this has something to do with Cloudflare's HTTP Proxy. This comment says: "If you're using CloudFlare, please disable auto-minification of HTML."

So far, I can't figure out how to do that. It's hard for me to find good information on what exactly Cloudflare does with their HTTP Proxy, and how I can configure it.


Questions:

  • Why exactly does this bug happen?
  • Where can I find information about what exactly the "orange cloud" does?
  • What is the best way to fix this problem while maintaining the benefits of Cloudflare's HTTP Proxy?
like image 508
chadoh Avatar asked Mar 09 '23 22:03

chadoh


1 Answers

React on the server needs to render the application to a string of HTML that makes sense to the browser. At the same time, React in the browser needs to read this HTML and understand it in relation to your JS code: it needs to identify which DOM tree came from which React component, in a very detailed way. Thus, in effect, the intermediate HTML is a serialization format between React on the server and React on the client with an additional requirement for it to make sense for the browser even in the absence of React.

When you enable advanced Cloudflare functionality, it treats the HTML as a “regular” HTML, not fancy server-side rendered compnents. My baseless speculation on one thing that could be going wrong is stripping HTML comments. In general, this is a natural thing to do for minification. But React uses HTML comments to put a <!-- empty --> placeholder where a React component returns null. Naturally, stripping these breaks React.

Cloudflare is there to make serving websites faster at a lower cost. They have a wide variety of tools to achieve that, see their introduction guide. Minifying HTML is completely natural and it is unfortunate it breaks your use case, but this is what we get when the meaning of nodes and attributes and flexibility changing them in our HTML is not strictly defined.

I think the most straight-forward way for you to move forward for now is to disable HTML minification in Cloudflare settings.

like image 179
Denis Avatar answered Mar 11 '23 12:03

Denis