Injecting JavaScript into React Native Webview

Sometimes we want to control the Webview and/or get a response from the Webview, Just for that, the Webview has injectedJavaScript prop.

Idan Levi

--

Photo by Sara Bakhshi on Unsplash

In some cases we want to change elements in Webview such as button color, in other cases, we want to add elements such as text or image.
we can do it with injection code to Webview.

Let’s change the header background color of the official react-native website to purple 🍆

import React, { Component } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';
export default class app extends Component {
constructor(props) {
super(props);
this.state = { webViewUrl: 'https://reactnative.dev' };
}
render() {
const jsCode = `document.querySelector('.HeaderHero').style.backgroundColor = 'purple';`;
return (
<View style={styles.container}>
<WebView
ref={ref => {
this.webview = ref;
}}
source={{ uri: this.state.webViewUrl }}
originWhitelist={['*']}
javaScriptEnabledAndroid={true}
injectedJavaScript={jsCode}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
}
});

Let’s move on to another more interesting ability, get an answer from the Webview after a particular trigger.
We’ll use postMessage & onMessage for this and implement on the same above code,
we did some changes on the “Get started” button —
we changed the button color to green and we added a listener for click on the button and we catch this trigger and handle the data that we get from the Webview:

import React, { Component } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';
export default class app extends Component {
constructor(props) {
super(props);
this.state = { webViewUrl: 'https://reactnative.dev' };
}
_onMessage = event => {
console.log('_onMessage', JSON.parse(event.nativeEvent.data));
const res = JSON.parse(event.nativeEvent.data);
if (res.message === 'ok') {
alert('button clicked');
}
};
render() {
const jsCode = `document.querySelector('.HeaderHero').style.backgroundColor = 'purple';
document.querySelector('a.ActionButton').style.backgroundColor = 'green';
document.querySelector('a.ActionButton').addEventListener("click", function() {
window.ReactNativeWebView.postMessage(JSON.stringify({type: "click", message : "ok"}));
});
true;`;
return (
<View style={styles.container}>
<WebView
ref={ref => {
this.webview = ref;
}}
source={{ uri: this.state.webViewUrl }}
originWhitelist={['*']}
javaScriptEnabledAndroid={true}
injectedJavaScript={jsCode}
onMessage={this._onMessage}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});

You can control a lot of elements and make a lot of changes, it’s an amazing tool, plus Webview has features that come with the library like onNavigationStateChange or onLoadEnd that can help in these cases.

--

--