Skip to main content

Working with WebView

1. Installing WebView

To use WebView in an Expo project, you need to install the @react-native-webview/webview package.

Example: Install WebView

npm install @react-native-webview/webview

After installation, you must configure your project to use the WebView component. For Expo managed projects, you may need to run:

Example: Configure Expo

expo install @react-native-webview/webview
Step Description Notes
1 Install the WebView package Use npm install or expo install
2 Link the package (if needed) For Expo Go, linking is handled automatically
3 Import WebView in your component Use import { WebView } from 'react-native-webview'

2. Creating WebView Component

Example: Basic WebView Component

import { WebView } from 'react-native-webview';

<WebView
  source={{ uri: &#x27;https://expo.dev&#x27; }}
  style={{ flex: 1 }}
/>
Property Description Default Notes
source URL or HTML content to display null Required. Can be a URL string or object with uri property
style Styling for the WebView component {} Must include flex: 1 to fill container
javaScriptEnabled Enables JavaScript execution true Set to false for security in read-only content
scalesPageToFit Enables page scaling true Controls whether content scales to fit the screen
Note: The WebView component requires proper styling to display content correctly. Always set flex: 1 in the style prop to ensure it fills its container.

3. Loading URLs

Property Values Description
source { uri: 'https://example.com' } URL to load in the WebView
source { html: '<html><body>Hello</body></html>' } HTML string to render

Example: Loading a URL

import { WebView } from 'react-native-webview';

<WebView
  source={{ uri: 'https://expo.dev' }}
  style={{ flex: 1 }}
/>
Note: On iOS, you may need to add NSAppTransportSecurity to your Info.plist for non-HTTPS URLs.

4. Loading HTML Content

Example: Loading Local HTML File

import { WebView } from &#x27;expo-web-browser&#x27;;

<WebView
  source={{ uri: &#x27;file:///android_asset/web/index.html&#x27; }}
  style={{ flex: 1 }}
/>
Property Description Values
source HTML content to load uri, html, or file
style Styling for the WebView component Object with standard style properties
Note: On Android, assets must be placed in android/app/src/main/assets.

5. Handling Navigation

Example: Basic WebView Navigation

import { WebView } from 'react-native-webview';

<WebView
  source={{ uri: 'https://expo.dev' }}
  onNavigationStateChange={(navState) => {
    console.log('Current URL:', navState.url);
  }}
/>
Property Description Values
onNavigationStateChange Callback when navigation state changes function
navigationState Current navigation state object object
Note: The navigationState object includes properties like url, title, and canGoBack.

Example: Handling Back Navigation

import { WebView } from 'react-native-webview';

<WebView
  source={{ uri: 'https://expo.dev' }}
  onNavigationStateChange={(navState) => {
    if (navState.canGoBack) {
      console.log('Can go back');
    }
  }}
/>

6. Injecting JavaScript

Example: Injecting JavaScript into WebView

import { WebView } from 'react-native-webview';

const injectedJavaScript = `
  const newTitle = 'Injected Title';
  document.title = newTitle;
  true; // required for injecting a script
`;

<WebView
  source={{ uri: 'https://example.com' }}
  injectedJavaScript={injectedJavaScript}
/>
Property Description Values
injectedJavaScript JavaScript code to inject into the WebView string
injectedJavaScriptBeforeContentLoaded JavaScript to inject before content is loaded string
Note: The injected JavaScript must return true to indicate successful execution.

7. Communicating with Web Page

Expo WebView provides several mechanisms to communicate between the native app and the web page content. These include:

  • postMessage from web to native
  • injectJavaScript from native to web

Example: Sending message from web to native

// In your web page
window.ReactNativeWebView.postMessage("Hello from web");

Example: Receiving message in native app

// In your React Native component
<WebView
  source={{ uri: 'https://example.com' }}
  onMessage={(event) => {
    console.log("Received from web:", event.nativeEvent.data);
  }}
/>

Example: Sending message from native to web

// In your React Native component
const injectJavaScript = `
  window.myAppData = {
    userId: '12345',
    theme: 'dark'
  };
  true; // Required for injectJavaScript to work
`;

<WebView
  source={{ uri: 'https://example.com' }}
  injectedJavaScript={injectJavaScript}
/>
Method Description Usage
onMessage Callback for messages sent from web to native onMessage={(event) => console.log(event.nativeEvent.data)}
postMessage Method available in web context to send data to native window.ReactNativeWebView.postMessage('data')
injectedJavaScript JavaScript to inject into the web page before it loads injectedJavaScript={jsCode}
Note: The postMessage method is only available in the web context when using Expo WebView. It's not a standard DOM API but an Expo-specific extension.

8. Handling Messages

Example: Receiving and Sending Messages

import React from 'react';
import { WebView } from 'react-native';

const WebViewExample = () => {
  const [messages, setMessages] = React.useState([]);

  const handleMessage = (event) => {
    const message = event.nativeEvent.data;
    setMessages(prev => [...prev, message]);
  };

  const sendMessageToWebView = () => {
    const webViewRef = React.useRef();
    webViewRef.current?.injectJavaScript('window.postMessage("Hello from React Native", ' + '"*")');
  };

  return (
    <WebView
      ref={webViewRef}
      source={{ uri: 'https://example.com' }}
      onMessage={handleMessage}
      javaScriptEnabled={true}
    />
  );
};

export default WebViewExample;
Property Description Notes
onMessage Callback function when a message is received from the WebView Receives an event object with nativeEvent.data
injectJavaScript Method to inject JavaScript into the WebView Used to send messages from React Native to WebView
Note: Messages are sent using window.postMessage in the WebView and received via onMessage in React Native.
Warning: Ensure that the WebView's javaScriptEnabled is set to true for message handling to work.

9. Managing WebView State

Example: Setting initial state in WebView

import { WebView } from 'react-native-webview';

const initialHtml = `
<html>
<head></head>
<body>
  <div id="app"></div>
  <script>
    window.appState = {
      user: { name: 'John Doe', isLoggedIn: true },
      theme: 'dark'
    };
  </script>
</body>
</html>`;

<WebView
  source={{ html: initialHtml }}
  startInLoadingState={true}
/>
Property Description Values
injectJavaScript Injects JavaScript into the WebView after it loads string
injectedJavaScript JavaScript to inject when WebView loads (deprecated) string
injectedJavaScriptBeforeContentLoaded JavaScript to inject before content loads string
Note: Use injectJavaScript for dynamic state updates after WebView loads.

Example: Updating WebView state with injectJavaScript

const updateAppState = (newState) => {
  const script = `
    window.appState = ${JSON.stringify(newState)};
    console.log('WebView state updated:', window.appState);
  `;
  webViewRef.current.injectJavaScript(script);
};

// Usage
updateAppState({ user: { name: 'Jane Doe', isLoggedIn: true }, theme: 'light' });

State Management Best Practices

  • Use injectJavaScript to update state after WebView loads
  • Pass initial state via source={{ html: ... }}
  • Avoid frequent injections; batch updates when possible
  • Use postMessage for communication between WebView and React Native

10. Configuring User Agent

Property Values Description
userAgent string Sets the user agent string for the WebView. Can be used to identify the app or modify browser behavior.
userAgentWithApplication boolean When true, appends the application name and version to the default user agent string.

Example: Setting Custom User Agent

import { WebView } from 'react-native-webview';

<WebView
  source={{ uri: 'https://example.com' }}
  userAgent="MyApp/1.0 (Custom User Agent)"
/>

Example: Using Application User Agent

import { WebView } from 'react-native-webview';

<WebView
  source={{ uri: 'https://example.com' }}
  userAgentWithApplication={true}
/>

11. Handling Loading States

Example: Basic WebView with Loading Indicators

import React, { useState } from 'react';
import { WebView } from 'react-native-webview';

const MyWebView = () => {
  const [loading, setLoading] = useState(true);

  return (
    <WebView
      source={{ uri: 'https://example.com' }}
      startInLoadingState={true}
      renderLoading={() => <div><span>Loading...</span></div>}
      onLoadEnd={() => setLoading(false)}
    />
  );
};
Property Description Default
startInLoadingState Whether to show the loading indicator before the WebView loads. false
renderLoading Custom component to render during loading. null
onLoadEnd Called when the WebView finishes loading or fails. null
Note: The renderLoading prop is not supported on all platforms. On iOS, it's only available in React Native versions 0.63 and above.

12. Enabling DOM Storage

Property Values Description
domStorageEnabled true | false Enables or disables DOM storage. Defaults to false.

Example: Enable DOM Storage in WebView

{ "domStorageEnabled": true }
Note: Enabling DOM storage allows the WebView to store data in local storage, which can be useful for caching or persisting state between sessions.

Was this article helpful?