First, install react-native-webview in your project:

npm install react-native-webview

Define a <SignatureApiWebView/> component to embed the WebView that displays the ceremony to the recipient and handles the ceremony events: completed, canceled, and failed.

import React, { useCallback } from 'react';
import { WebView, WebViewNavigation } from 'react-native-webview';
import Constants from 'expo-constants';


interface SignatureApiWebViewProps {
  ceremonyUrl: string;
}

export function SignatureApiWebView(props: SignatureApiWebViewProps) {
  const { ceremonyUrl } = props;

  const [showWebview, setShowWebview] = React.useState<boolean>(true);

  // Add these query parameters to the ceremony URL to make it embeddable
  // If you want to hide the cancel button (for example, if you want to
  // place the cancel button outside the embedded app) append the query
  // parameter `&allow_cancel=false`.

  const embeddedCeremonyUrl = props.ceremonyUrl + "&embedded=true&event_delivery=redirect";

  // This function handles the ceremony events (completed, canceled, and failed)

  const handleNavigation = useCallback((navigationState: WebViewNavigation): void => {
    try {

      // Extract the protocol (e.g. signatureapi-message:)
      // and eventType from the intercepted URL

      const interceptedUrl = navigationState.url;
      const parsedUrl = new URL(interceptedUrl);
      const protocol = parsedUrl.protocol;
      const eventType = parsedUrl.host;

      // Intercept signatureapi-message:// URLs

      if (protocol === 'signatureapi-message:') {
        switch (eventType) {
          case 'ceremony.completed':
            console.log('Ceremony completed');
            // Handle ceremony completion
            // Hide WebView
            setShowWebview(false);
            return;
          case 'ceremony.canceled':
            console.log('SignatureAPI ceremony canceled');
            // Handle ceremony cancellation
            // Hide WebView
            setShowWebview(false);
            return;
          case 'ceremony.failed':
            console.log('Ceremony failed');
            // Handle ceremony failure
            // Hide WebView
            setShowWebview(false);
            return;
          default:
            console.log(`Unhandled event detected: ${eventType}`);
            return;
        }
      }
    } catch (error) {
      console.error('Error handling navigation:', error);
    }
  }, []);

  return (
    <>
    {
      showWebview && <WebView
        source={{ uri: embeddedCeremonyUrl }}
        onNavigationStateChange={handleNavigation}
        originWhitelist={['*']}
        style={{ flex: 1, marginTop: Constants.statusBarHeight }}
      />
    }
    </>
  );
};

The mobile app retrieves a Ceremony URL from its backend and embeds it in the application using the <SignatureApiWebView/> component.

// The ceremony URL returned by the backend
const ceremonyUrl = "https://sign.signatureapi.com/en/start?token=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MjI4OTE3NDYsImV4cCI6MTcyMzQ5NjU0NiwiY2VyZW1vbnlf"

<SignatureApiWebView ceremonyUrl={ceremonyUrl}/>