WebView in React Native

Sahil BhosaleSahil Bhosale
10 min read

In the world of mobile app development, React Native stands out as a robust framework for building cross-platform applications. One of the key components available in React Native for integrating web content into mobile apps is WebView. So let's see few things about WebView

What is a WebView?

A WebView in React Native is a component that allows you to display web content (like websites or HTML pages) directly within your mobile app. It's essentially a mini web browser embedded in your application.
It is independent of any app's control over it's content

We use WebView in React Native through the react-native-webview package. This community-maintained library provides a feature-rich WebView component that offers various functionalities.

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

const App = () => {
  return (
    <View style={styles.container}>
      <WebView 
        source={{ uri: 'https://www.example.com' }} 
        style={styles.webview}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  webview: {
    flex: 1,
  },
});

export default App;

The source prop specifies the URL to be loaded.

Advanced Features and Configuration

1. Loading Local HTML Files

WebView can also load local HTML files. This is useful when you want to include static web content within your app.

<WebView 
  originWhitelist={['*']} 
  source={require('./local-file.html')} 
/>
//originWhitelist={['*']}: Allows loading content from any origin.

2. Injecting JavaScript

WebView allows you to inject JavaScript code into the web page being loaded. This can be useful for manipulating the DOM or communicating with the web content.

<WebView 
  source={{ uri: 'https://www.example.com' }} 
  injectedJavaScript={`document.body.style.backgroundColor = 'blue';`}
/>

3. Handling Navigation

You can control the navigation within WebView using the onNavigationStateChange prop. This allows you to monitor URL changes and handle them accordingly.

jsxCopy code<WebView 
  source={{ uri: 'https://www.example.com' }} 
  onNavigationStateChange={(event) => {
    if (event.url !== 'https://www.example.com') {
      // Handle the navigation event
    }
  }}
/>

Communication between WebView and App

There are several methods for communication between WebView and native apps in React Native.

  • PostMessage API: This is a widely used and recommended approach. It allows two-way communication between the WebView and the native app by sending messages through the window.postMessage method in JavaScript. Libraries like react-native-webview-bridge simplify the process by providing a bridge between the two contexts.

  • User Cookies: While not ideal for real-time communication, cookies can be used to store and share some data between the WebView and the native app. However, rely heavily on cookies can be insecure and present limitations for managing complex data exchange.

  • User Agent: The User-Agent header identifies the software making the request. While not typically used for direct communication, it can provide the native app with information about the browser engine used within the WebView, which might be helpful for specific functionalities.

Post Message Integration

// In your React Native component
import React, { useRef } from 'react';
import { View, Button } from 'react-native';
import { WebView } from 'react-native-webview';

const WebViewExample = () => {
  const webViewRef = useRef(null);

  const sendMessageToWebView = () => {
    webViewRef.current.injectJavaScript(`
      document.body.style.backgroundColor = 'lightblue';
      window.ReactNativeWebView.postMessage('Color changed!');
      true;
    `);
  };

  const handleWebViewMessage = (event) => {
    console.log('Message from WebView:', event.nativeEvent.data);
  };

  return (
    <View style={{ flex: 1 }}>
      <WebView
        ref={webViewRef}
        source={{ html: '<h1>Hello WebView!</h1>' }}
        onMessage={handleWebViewMessage}
      />
      <Button title="Change WebView Color" onPress={sendMessageToWebView} />
    </View>
  );
};

export default WebViewExample;

This example:

  1. Creates a WebView with simple HTML content

  2. Includes a button that, when pressed, changes the WebView's background color

  3. Sends a message from the WebView back to React Native

  4. Logs the message received from the WebView

Cookies and WebView:
Cookies are small pieces of data that websites store on a user's device. They are used to remember information about the user, such as login credentials, preferences, or browsing history.

Cookie Manager:

The most common approach for cookie management in React Native, especially with WebView, is to utilize third-party libraries. A popular option is @react-native-cookies/cookies This library provides a unified API for managing cookies on both Android and iOS, simplifying the development process.
Installation: npm install @react-native-cookies/cookies
API: The library offers functions to set, get, getAll, and deleteAll cookies for a specific URL.

import React, { useRef } from 'react';
import { WebView } from 'react-native-webview';
import CookieManager from '@react-native-cookies/cookies';

const MyWebView = () => {
  const webViewRef = useRef(null);

  const handleLoad = async () => {
    // Check if a specific cookie exists before loading the content
    const hasCookie = await CookieManager.get('isLoggedIn', 'https://example.com');
    if (hasCookie) {
      console.log('User is logged in based on cookie');
    } else {
      console.log('User is not logged in (or cookie does not exist)');
    }
  };

  const setLoginCookie = async () => {
    try {
      await CookieManager.set('isLoggedIn', 'true', 'https://example.com');
      console.log('Login cookie set successfully!');
    } catch (error) {
      console.error('Error setting login cookie:', error);
    }
  };

  return (
    <WebView
      ref={webViewRef}
      source={{ uri: 'https://example.com' }}
      onLoad={handleLoad}
    />
  );
};

export default MyWebView;

User Agent:
The User-Agent string is a header field included in HTTP requests sent by a web browser to a web server. It provides information about the software making the request, typically including:

  • Browser Name and Version: This identifies the specific browser (e.g., Chrome, Safari, Firefox) and its version number.

  • Operating System: The operating system of the device where the browser is running (e.g., Android, iOS, Windows).

  • Additional Information: Some user agents might include details about the device model, browser engine, or other relevant specifications.

    In React Native, when you use a WebView, you can set or modify the user agent string. This allows you to control how your WebView identifies itself to websites. Why it's important:

    • Differentiating traffic: Websites can distinguish between requests coming from your app's WebView and regular browser traffic.

    • Customized content: Some websites serve different content based on the user agent.

    • Analytics: It helps in tracking and analyzing app usage vs. web usage.

The react-native-webview library provides a comprehensive set of props to customize the WebView component's behavior in React Native applications.

Complete Example with Multiple Props

Here's a comprehensive example demonstrating several of the props:

import React from 'react';
import { StyleSheet, View, ActivityIndicator, Alert } from 'react-native';
import { WebView } from 'react-native-webview';

const App = () => {
  const handleMessage = (event) => {
    Alert.alert('Message from WebView', event.nativeEvent.data);
  };

  const handleNavigationStateChange = (navState) => {
    console.log('Current URL:', navState.url);
  };

  return (
    <View style={styles.container}>
      <WebView 
        source={{ uri: 'https://www.example.com' }}
        style={styles.webview}
        onLoad={() => alert('Page loaded!')}
        onError={() => alert('Error loading page!')}
        onNavigationStateChange={handleNavigationStateChange}
        injectedJavaScript="document.body.style.backgroundColor = 'red';"
        onMessage={handleMessage}
        startInLoadingState={true}
        renderLoading={() => <ActivityIndicator color="blue" />}
        scalesPageToFit={true}
        javaScriptEnabled={true}
        domStorageEnabled={true}
        mediaPlaybackRequiresUserAction={false}
        allowsInlineMediaPlayback={true}
        mixedContentMode="always"
        userAgent="MyCustomUserAgent"
        sharedCookiesEnabled={true}
        onLoadProgress={({ nativeEvent }) => console.log(nativeEvent.progress)}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  webview: {
    flex: 1,
  },
});

export default App;

Explanation

  • source: Loads the specified URL.

  • style: Applies styles to the WebView.

  • onLoad: Alerts when the page finishes loading.

  • onError: Alerts when there is an error loading the page.

  • onNavigationStateChange: Logs the current URL.

  • injectedJavaScript: Changes the background color of the page.

  • onMessage: Alerts with a message from the web content.

  • startInLoadingState: Shows a loading indicator while the page loads.

  • renderLoading: Customizes the loading indicator.

  • scalesPageToFit: Adjusts the page to fit the WebView.

  • javaScriptEnabled: Enables JavaScript.

  • domStorageEnabled: Enables DOM storage.

  • mediaPlaybackRequiresUserAction: Allows media playback without user action.

  • allowsInlineMediaPlayback: Allows inline media playback.

  • mixedContentMode: Handles mixed content.

  • userAgent: Sets a custom user agent.

  • sharedCookiesEnabled: Enables shared cookies.

  • onLoadProgress: Logs the loading progress.

This example showcases how to use multiple props to create a customized WebView experience in a React Native application.

Best Practices

1. Security
When using WebView, it is crucial to consider security implications. Ensure that you:

  • Restrict navigation to trusted domains.

  • Avoid loading arbitrary HTML or executing untrusted JavaScript.

  • Use HTTPS to encrypt data in transit.

2. Performance
To optimize performance:

  • Avoid loading large web pages or complex scripts that can slow down the WebView.

  • Use local caching for frequently accessed content.

  • Minimize the use of injectedJavaScript and onMessage as they can introduce performance overhead.

3. Error Handling
Implement proper error handling for scenarios where the web content fails to load:

<WebView 
  source={{ uri: 'https://www.example.com' }} 
  renderError={(errorName) => <Text>Error: {errorName}</Text>}
/>

4. Testing
Ensure thorough testing of WebView functionality across different devices and OS versions to account for any platform-specific issues.

Why do many companies rely on WebView

  • The fact that many companies already have a web presence is a major driver for WebView adoption.

  • The ability to automatically reflect web content edits within the app makes WebView a compelling solution for companies that require dynamic and frequently updated content in their mobile apps.

  • By eliminating the need for frequent app store updates and ensuring users always see the latest content, WebView contributes to a more user-friendly and engaging mobile app experience

Advantages of Using WebView in React Native

1. Content Integration
Seamless Content Display: WebView enables the display of web content such as news articles, blogs, or documentation within the app, offering a seamless user experience without leaving the application environment.

2. Hybrid App Development
Flexible Development Approach: For projects with significant web-based functionality, WebView allows a hybrid approach, combining web technologies (HTML, CSS, JavaScript) with native components, reducing development time and resources.

3. Cross-Platform Consistency
Uniform User Experience: WebView ensures consistent display of web content across both iOS and Android platforms, maintaining a uniform user experience regardless of the device used.

4. Reuse of Existing Web Apps
Cost-Effective Development: If an existing web application is available, WebView can be used to wrap it into a mobile app, minimizing the effort and cost of creating a separate mobile version.

5. Rapid Updates
Efficient Content Updates: With WebView, web content can be updated on the server-side without needing to release a new version of the app. This is ideal for apps requiring frequent updates, such as news or e-commerce apps.

6. Reduced Development Time
Quick Implementation: Using WebView to embed web content can significantly speed up the development process, especially when compared to building equivalent functionality using native code.

7. Access to Web Ecosystem
Utilize Web Libraries and Tools: Developers can leverage existing web libraries, frameworks, and tools, reducing the need to reinvent the wheel and allowing for a more efficient development process.

8. Simplified Content Management
Centralized Content Control: Managing content through a web interface allows for centralized control and easier updates, which is particularly useful for dynamic content and content-driven applications.

Cons of it

Performance Issues

  1. Resource Intensive:
    WebView can be resource-intensive, leading to higher memory and CPU usage compared to native components. This can result in slower performance, especially on older or less powerful devices.
    2. Loading Time:
    Web pages, especially those with heavy content, can take longer to load within a WebView compared to native screens. This can negatively impact the user experience due to increased wait times.

User Experience
1. Inconsistent UI/UX:
Web content may not always blend seamlessly with the native components of your app, leading to inconsistent user interface and user experience. This can make the app feel less cohesive and polished.
2. Limited Native Features:
WebView does not have access to all native device features. Although you can communicate between WebView and the native side, it requires additional effort and may not be as efficient as using native components directly.

Security Risks
1. Vulnerability to Attacks:
WebView can expose your app to security vulnerabilities such as cross-site scripting (XSS) attacks, if not properly handled. Loading arbitrary HTML or executing untrusted JavaScript within WebView can be particularly risky.
2. Phishing Risks:
Since WebView can load external web pages, it might be exploited for phishing attacks if not carefully managed. Users could be tricked into entering sensitive information on a malicious web page.

Development and Maintenance
1. Complex Debugging:
Debugging issues within WebView can be more complex compared to native components. You need to manage both the web and native codebases, which can complicate the development process.
2. Increased Maintenance:
Maintaining a hybrid application that uses WebView requires keeping both web and native components up-to-date. This can lead to increased maintenance overhead and potential synchronization issues.
3. Dependency on WebView Library:
Using WebView in React Native requires reliance on the react-native-webview library, which means you must keep up with updates and changes in the library. Any breaking changes or deprecated features in the library can impact your app.

Conclusion

WebView in React Native is a useful tool that lets you add web content to your mobile apps. It helps you combine web and app development, making it easier and faster to update your app with new content. By using WebView, developers can enhance their apps with web features, creating a richer experience for users. Though there are some downsides, knowing the benefits and following best practices can help you overcome these challenges and get the most out of WebView in your React Native apps.

4
Subscribe to my newsletter

Read articles from Sahil Bhosale directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sahil Bhosale
Sahil Bhosale

Aspiring Developer