Intercom Widget don't want to work inside React Native WebView (Android only!)

Hey!

We have a React Native app (Expo) and a website. We successfully integrated Intercom widget on a website and now tries to show the same widget inside our RN app.

Since we are using managed RN app by Expo and eject is not an option for us (we don’t want to loose capabilities of Expo) we can’t add and link react-native-intercom library into project.

The simple and logical solution was utilize WebView (react-native-webview) and render widget inside it.

On iOS it works like a charm! The sexy widget appears and can be managed through communication between RN app and WebView using postMessage/onMessage technique.

But on Android I see only white screen. No widget icon appeared. I spent a lot of time struggling with it and googling, no solution.

As an experiment I developed a pure native Android app, created Activity and attached native WebView to it. In Chrome dev tools I started to debug WebView to understand what’s going on. No errors during script running. The first script widget loads fine. Only one thing I’ve found is:

When frame-modern.d209035c.js and vendor-modern.651d8a21.js requests, the WebView prints net::ERR_CONTENT_DECODING_FAILED.

I assume that exactly that error breaks the widget bootstraping and showing.

Maybe someone had the similar problem and found a workaround?

Hello there! :wave:

Kayvan from Intercom customer support here. I was able to gather some information from one of our Support Engineers around this. We have two Messenger JavaScript bundles, one for modern ES2015 capable browsers and one for everything else. Files in the modern bundle have a somefile-modern.js naming pattern. All ES2015 capable browsers also support Brotli compression, so our Messenger team have opted to compress the modern bundle using Brotli, and leave the legacy bundle as gzip.


The basic android webview needs special treatment for such cases. If the webview only includes the header “accept-encoding:gzip, deflate” and our Messenger is sending content with br (brotli) encoding, it could lead to Error 330 (net::ERR_CONTENT_DECODING_FAILED): (Google Chrome).

Because the webview is super strict and says “I told the server I only understand gzip and deflate”, it can’t handle the br encoding because it was not expected.

Hope this comes in handy! If you’d like to speak further on this, please feel free to reach out to us through the Messenger on intercom.com and we are happy to loop in one of our Support Engineers to assist.

Hi!

Thanks for a quick response!

All you said makes a lot of sense. Well, in react-native-webview we can’t intercept each resource request on Android (again, it works on iOS), and that’s why we can’t add accept-encoding header for each request. It’s a known bug in RN WebView which opened for a couple of years and not fixed.

However, what did the trick is to set a User Agent to WebView! In my case for Android only I set pretty OLD User Agent Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36 and finally widget appeared.

I think the trick in loading of not modern js libs (or create an illusion for server that WebView does not support Brotli) for Android WebView for now.

I am having this exact same issue with my app. How did you set the user agent in WebView…?

If we are speaking about RN app then RN WebView has prop userAgent.
I used this code:

For pure native Android app you can use this:

1 Like

Awesome, thank you. We have our web app packaged up in a RN WebView so I’ll ask our wrapper provider to add this in to the native code as I can only play with the HTML. Any way you think I could achieve this through HTML only…?

Hmmm… In my situation I use WebView only for showing Intercom widget in full screen mode in separate screen (using react-navigation). All other views and components written on RN.

In your case I don’t know how will behave your entire app inside WebView with manually setted old user agent. And I’m not sure that setting user agent for whole app just to force Intercom to work is a good idea. It may lead to another unexpected results related to your own app. But you can try :slight_smile:

No, you can’t override user agent from HTML. It should be set from native layer before WebView loading.

Facing the exact same issue but User Agent trick doesn’t work

We have the same issue - entire webapp using intercom is wrapped in RN webview.
The useragent hack holds the risk of introducing a host of new problems.
According to Kayvan the problem is that the server doesn’t respect the accept-encoding header and wrongly assumes that the browser will accept brotli.
Are you planning to fix the bug?

I’ve contacted support to see if there’s any way you can force load the old JS bundles at the HTML level when booting Intercom… I suspect not but you never know