This gist documents a workaround for Expo 56 DOM Components when using:
<MyDOMComponent
dom={{
useExpoDOMWebView: false,
}}
/>The goal is to keep Expo DOM Components, but run them through react-native-webview instead of @expo/dom-webview.
In this project, @expo/dom-webview was not usable in production because of Android bridge failures such as:
Error: Call to function 'DomWebView.injectJavaScript' has been rejected.
-> Caused by: The 1st argument cannot be cast to type class expo.modules.webview.DomWebView (received class java.lang.Integer)
-> Caused by: Unable to find the class expo.modules.webview.DomWebView view with tag 1028On iOS, @expo/dom-webview also did not expose the same control surface as react-native-webview; in particular, it did not let us remove the iOS keyboard accessory toolbar.
So the preferred setup was:
dom={{
useExpoDOMWebView: false,
}}That switches Expo DOM Components to react-native-webview.
Expo DOM Components expect bootstrap data to exist before the DOM bundle starts:
window.$$EXPO_DOM_HOST_OSwindow.$$EXPO_INITIAL_PROPS
In production, with useExpoDOMWebView: false, the generated DOM HTML may assume that this function exists:
window.ReactNativeWebView.injectedObjectJson()But with react-native-webview, that method is not always available early enough. This can produce errors like:
Failed to parse injectedObjectJson: window.ReactNativeWebView.injectedObjectJson is not a function
Top OS ($$EXPO_DOM_HOST_OS) is not defined. This is a bug in the DOM Component runtime.After adding a simple fallback, another race can appear: the DOM component may render once with empty fallback props, causing app-level crashes such as:
Cannot read properties of undefined (reading 'colors')That happens because the component rendered before the real marshalled props arrived.
There are two Yarn patches:
-
expo-npm-56.0.12.patch- injects
$$EXPO_DOM_HOST_OSand$$EXPO_INITIAL_PROPSthroughinjectedJavaScriptBeforeContentLoaded; - re-sends the current props on WebView
onLoad; - teaches
expo/dom/entryto rendernullwhile fallback props are marked as pending.
- injects
-
@expo-cli-npm-56.1.16.patch- patches the generated DOM HTML;
- stops throwing when
injectedObjectJson()is missing; - adds an OS fallback from the user agent;
- creates minimal fallback props;
- marks fallback props as pending so the DOM component waits for the real
$$propsmessage before rendering.