diff --git a/README.md b/README.md
index 1b1ed8f8..6180b9e9 100644
--- a/README.md
+++ b/README.md
@@ -228,49 +228,114 @@ This library works on MacOS 10.15+ if using in conjunction with [react-native-ma
 
 ### Web (not react-native-web, but that may come as a follow-on, this is pure web at the moment)
 
+### WebView
+
 #### 1. Initial set-up
-- Ensure you follow the android steps above.
-- Install the [web counterpart](https://github.com/A-Tokyo/react-apple-signin-auth) `yarn add react-apple-signin-auth` in your web project.
+- Make sure to correctly configure your Apple developer account to allow for proper web based authentication.
+- Install the [React Native WebView](https://github.com/react-native-webview/react-native-webview) `yarn add react-native-webview` (or) `npm i react-native-webview` in your project. [Link native dependencies](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Getting-Started.md#2-link-native-dependencies).
+- Your backend needs to implement web based authentification
 
-#### 2. Implement the login process on web
+#### 2. Implement the login process
 ```js
-import AppleSignin from 'react-apple-signin-auth';
-
-/** Apple Signin button */
-const MyAppleSigninButton = ({ ...rest }) => (
-  <AppleSignin
-    /** Auth options passed to AppleID.auth.init() */
-    authOptions={{
-      clientId: 'SAME AS ANDROID',
-      redirectURI: 'SAME AS ANDROID',
-      scope: 'email name',
-      state: 'state',
-      /** sha256 nonce before sending to apple to unify with native firebase behavior - https://github.com/invertase/react-native-apple-authentication/issues/28 */
-      nonce: sha256('nonce'),
-      /** We have to usePopup since we need clientSide authentication */
-      usePopup: true,
-    }}
-    onSuccess={(response) => {
-      console.log(response);
-      // {
-      //     "authorization": {
-      //       "state": "[STATE]",
-      //       "code": "[CODE]",
-      //       "id_token": "[ID_TOKEN]"
-      //     },
-      //     "user": {
-      //       "email": "[EMAIL]",
-      //       "name": {
-      //         "firstName": "[FIRST_NAME]",
-      //         "lastName": "[LAST_NAME]"
-      //       }
-      //     }
-      // }
-    }}
-  />
-);
-
-export default MyAppleSigninButton;
+
+// App.js
+import React from "react";
+import {
+  View,
+  TouchableWithoutFeedback,
+  Text
+} from "react-native";
+import {
+  appleAuth,
+  appleAuthAndroid,
+  AppleAuthWebView // Internaly using WebView
+} from "@invertase/react-native-apple-authentication";
+
+function onAppleLoginWebViewButtonPress() {
+
+  // https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms
+  const appleAuthConfig = {
+    // The Service ID you registered with Apple
+    clientId: "com.example.client-web",
+
+    // Return URL added to your Apple dev console. It must still match the URL you provided to Apple.
+    redirectUri: "https://example.com/auth/callback",
+
+    // The type of response requested - code, id_token, or both.
+    responseType: "code id_token",
+
+    // The amount of user information requested from Apple.
+    scope: "name email"
+
+    // Random nonce value that will be SHA256 hashed before sending to Apple.
+    // nonce: nonce,
+
+    // Unique state value used to prevent CSRF attacks. A UUID will be generated if nothing is provided.
+    // state: state
+  };
+
+  this.setState(
+    {
+      appleAuthConfig: appleAuthConfig
+    }
+  );
+}
+
+function onAppleAuthResponse(responseContent) {
+
+  // Handle your server response (after login - apple redirects to your server url)
+  console.log("onAppleAuthResponse responseContent", responseContent);
+}
+
+// If no iOS or Android is supported than we use webView fallback with custom button
+function App() {
+
+  render() {
+    const appleAuthConfig = this.state.appleAuthConfig;
+
+    if (appleAuthConfig) {
+      return (
+        <AppleAuthWebView
+          config={appleAuthConfig}
+          // optional loadingIndicator property
+          // loadingIndicator={
+          //   () => {
+          //     return (
+          //       <Loading />
+          //     );
+          //   }
+          // }
+          onResponse={this.onAppleAuthResponse}
+        />
+      );
+    }
+  }
+
+  return (
+    <View>
+
+
+      {
+        // It makes sense to show the native buttons in a real app,
+        // something like the code below, but we are just demonstrating web login here so it is commented out
+
+        // (appleAuth.isSupported || appleAuthAndroid.isSupported) ? (
+        //   <AppleButton
+        //     buttonStyle={AppleButton.Style.BLACK}
+        //     buttonType={AppleButton.Type.SIGN_IN}
+        //     onPress={this.onAppleLoginButtonPress}
+        //   />
+        // )  // else add webView view button
+      }
+
+      <TouchableWithoutFeedback onPress={this.onAppleLoginWebViewButtonPress}>
+        <Text>
+          Sign in with Apple
+        </Text>
+      </TouchableWithoutFeedback>
+    </View>
+  );
+}
 ```
 
 #### 3. Verify serverside
@@ -278,6 +343,9 @@ export default MyAppleSigninButton;
 - See [Serverside Verification](#serverside-verification)
 - Ensure that you pass the clientID as the web service ID, not the native app bundle. Since the project utilizes the service ID for authenticating web and android.
 
+### WebView Config
+- https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms
+
 ## Serverside verification
 
 #### Nonce
diff --git a/example/app.android.js b/example/app.android.js
index faff15f7..d941dd10 100644
--- a/example/app.android.js
+++ b/example/app.android.js
@@ -16,21 +16,22 @@
  *
  */
 
-import React from 'react';
-import { StyleSheet, View, Image, Text } from 'react-native';
-import { AppleButton, appleAuthAndroid } from '@invertase/react-native-apple-authentication';
+import React, { useState } from 'react';
+import { StyleSheet, View, Image, TouchableOpacity, Text } from 'react-native';
+import { AppleButton, appleAuthAndroid, AppleAuthWebView } from '@invertase/react-native-apple-authentication';
 import 'react-native-get-random-values';
 import { v4 as uuid } from 'uuid'
 import appleLogoWhite from './images/apple_logo_white.png';
 import appleLogoBlack from './images/apple_logo_black.png';
+import { getAppleAuthConfig, parseAppleAuthResponse } from './app.shared';
 
-
-export default RootComponent = () => {
+export default function RootComponent() {
+  const [appleAuthConfig, setAppleAuthConfig] = useState(null);
 
   const doAppleLogin = async () => {
     // Generate secure, random values for state and nonce
     const rawNonce = uuid();
-    const state = uuid();
+    const rawState = uuid();
 
     try {
       // Initialize the module
@@ -63,7 +64,7 @@ export default RootComponent = () => {
 
         // [OPTIONAL]
         // Unique state value used to prevent CSRF attacks. A UUID will be generated if nothing is provided.
-        state,
+        state: rawState,
       });
 
       const response = await appleAuthAndroid.signIn();
@@ -96,70 +97,85 @@ export default RootComponent = () => {
     }
   };
 
+  if (appleAuthConfig) {
+    return (
+      <AppleAuthWebView
+        config={appleAuthConfig}
+        onResponse={
+          (responseContent) => {
+            setAppleAuthConfig(null);
+            parseAppleAuthResponse(responseContent);
+          }
+        }
+      />
+    );
+  }
+
   return (
     <View style={[styles.container, styles.horizontal]}>
-      {appleAuthAndroid.isSupported && (
-        <View>
-          <Text style={styles.header}>Buttons</Text>
+      {
+        appleAuthAndroid.isSupported && (
+          <View>
+            <Text style={styles.header}>Buttons</Text>
 
-          <Text style={{ marginBottom: 8 }}>Continue Styles</Text>
-          <AppleButton
-            style={{ marginBottom: 10 }}
-            cornerRadius={5}
-            buttonStyle={AppleButton.Style.WHITE}
-            buttonType={AppleButton.Type.CONTINUE}
-            onPress={() => doAppleLogin()}
-            leftView={(
-              <Image
-                style={{
-                  alignSelf: 'center',
-                  width: 14,
-                  height: 14,
-                  marginRight: 7,
-                  resizeMode: 'contain',
-                }}
-                source={appleLogoBlack}
-              />
-            )}
-          />
-          <AppleButton
-            style={{ marginBottom: 10 }}
-            cornerRadius={0}
-            buttonStyle={AppleButton.Style.WHITE_OUTLINE}
-            buttonType={AppleButton.Type.CONTINUE}
-            onPress={() => doAppleLogin()}
-            leftView={(
-              <Image
-                style={{
-                  alignSelf: 'center',
-                  width: 14,
-                  height: 14,
-                  marginRight: 7,
-                  resizeMode: 'contain',
-                }}
-                source={appleLogoBlack}
-              />
-            )}
-          />
-          <AppleButton
-            style={{ marginBottom: 16 }}
-            cornerRadius={30}
-            buttonStyle={AppleButton.Style.BLACK}
-            buttonType={AppleButton.Type.CONTINUE}
-            onPress={() => doAppleLogin()}
-            leftView={(
-              <Image
-                style={{
-                  alignSelf: 'center',
-                  width: 14,
-                  height: 14,
-                  marginRight: 7,
-                  resizeMode: 'contain',
-                }}
-                source={appleLogoWhite}
-              />
-            )}
-          />
+            <Text style={{ marginBottom: 8 }}>Continue Styles</Text>
+            <AppleButton
+              style={{ marginBottom: 10 }}
+              cornerRadius={5}
+              buttonStyle={AppleButton.Style.WHITE}
+              buttonType={AppleButton.Type.CONTINUE}
+              onPress={() => doAppleLogin()}
+              leftView={(
+                <Image
+                  style={{
+                    alignSelf: 'center',
+                    width: 14,
+                    height: 14,
+                    marginRight: 7,
+                    resizeMode: 'contain',
+                  }}
+                  source={appleLogoBlack}
+                />
+              )}
+            />
+            <AppleButton
+              style={{ marginBottom: 10 }}
+              cornerRadius={0}
+              buttonStyle={AppleButton.Style.WHITE_OUTLINE}
+              buttonType={AppleButton.Type.CONTINUE}
+              onPress={() => doAppleLogin()}
+              leftView={(
+                <Image
+                  style={{
+                    alignSelf: 'center',
+                    width: 14,
+                    height: 14,
+                    marginRight: 7,
+                    resizeMode: 'contain',
+                  }}
+                  source={appleLogoBlack}
+                />
+              )}
+            />
+            <AppleButton
+              style={{ marginBottom: 16 }}
+              cornerRadius={30}
+              buttonStyle={AppleButton.Style.BLACK}
+              buttonType={AppleButton.Type.CONTINUE}
+              onPress={() => doAppleLogin()}
+              leftView={(
+                <Image
+                  style={{
+                    alignSelf: 'center',
+                    width: 14,
+                    height: 14,
+                    marginRight: 7,
+                    resizeMode: 'contain',
+                  }}
+                  source={appleLogoWhite}
+                />
+              )}
+            />
 
           <Text style={{ marginBottom: 8 }}>Sign-in Styles</Text>
           <AppleButton
@@ -222,9 +238,32 @@ export default RootComponent = () => {
         </View>
       )}
 
-      {!appleAuthAndroid.isSupported && (
-        <Text>Sign In with Apple requires Android 4.4 (API 19) or higher.</Text>
-      )}
+      {
+        !appleAuthAndroid.isSupported && (
+          <View>
+            <Text>
+              Sign In with Apple requires Android 4.4 (API 19) or higher.
+            </Text>
+            <Text>
+              But in such cases you can always use apple webView sign in!
+            </Text>
+          </View>
+        )
+      }
+
+      {
+        <TouchableOpacity onPress={
+          () => {
+            setAppleAuthConfig(getAppleAuthConfig());
+          }
+        }>
+          <View style={styles.button}>
+            <Text style={styles.label}>
+              WebView sign in with Apple
+            </Text>
+          </View>
+        </TouchableOpacity>
+      }
     </View>
   );
 }
diff --git a/example/app.ios.js b/example/app.ios.js
index 38e84210..de9bcbf9 100644
--- a/example/app.ios.js
+++ b/example/app.ios.js
@@ -17,8 +17,9 @@
  */
 
 import React, { useState, useEffect } from 'react';
-import { StyleSheet, View, Text } from 'react-native';
-import { appleAuth, AppleButton } from '@invertase/react-native-apple-authentication';
+import { StyleSheet, View, Text, TouchableOpacity} from 'react-native';
+import { appleAuth, AppleButton, AppleAuthWebView } from '@invertase/react-native-apple-authentication';
+import { getAppleAuthConfig, parseAppleAuthResponse } from './app.shared';
 
 /**
  * You'd technically persist this somewhere for later use.
@@ -93,6 +94,8 @@ async function onAppleButtonPress(updateCredentialStateForUser) {
 
 export default function RootComponent() {
   const [credentialStateForUser, updateCredentialStateForUser] = useState(-1);
+  const [appleAuthConfig, setAppleAuthConfig] = useState(null);
+
   useEffect(() => {
     if (!appleAuth.isSupported) return;
 
@@ -112,64 +115,103 @@ export default function RootComponent() {
     });
   }, []);
 
-  if (!appleAuth.isSupported) {
+  if (appleAuthConfig) {
     return (
-      <View style={[styles.container, styles.horizontal]}>
-        <Text>Apple Authentication is not supported on this device.</Text>
-      </View>
+      <AppleAuthWebView
+        config={appleAuthConfig}
+        onResponse={
+          (responseContent) => {
+            setAppleAuthConfig(null);
+            parseAppleAuthResponse(responseContent);
+          }
+        }
+      />
     );
   }
 
   return (
     <View style={[styles.container, styles.horizontal]}>
-      <Text style={styles.header}>Credential State</Text>
-      <Text>{credentialStateForUser}</Text>
-
-      <Text style={styles.header}>Buttons</Text>
-      <Text>Continue Styles</Text>
-      <AppleButton
-        style={styles.appleButton}
-        cornerRadius={5}
-        buttonStyle={AppleButton.Style.WHITE}
-        buttonType={AppleButton.Type.CONTINUE}
-        onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
-      />
-      <AppleButton
-        style={styles.appleButton}
-        cornerRadius={5}
-        buttonStyle={AppleButton.Style.WHITE_OUTLINE}
-        buttonType={AppleButton.Type.CONTINUE}
-        onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
-      />
-      <AppleButton
-        style={styles.appleButton}
-        cornerRadius={5}
-        buttonStyle={AppleButton.Style.BLACK}
-        buttonType={AppleButton.Type.CONTINUE}
-        onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
-      />
-      <Text>Sign-in Styles</Text>
-      <AppleButton
-        style={styles.appleButton}
-        cornerRadius={5}
-        buttonStyle={AppleButton.Style.WHITE}
-        buttonType={AppleButton.Type.SIGN_IN}
-        onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
-      />
-      <AppleButton
-        style={styles.appleButton}
-        cornerRadius={5}
-        buttonStyle={AppleButton.Style.WHITE_OUTLINE}
-        buttonType={AppleButton.Type.SIGN_IN}
-        onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
-      />
-      <AppleButton
-        style={styles.appleButton}
-        cornerRadius={5}
-        buttonStyle={AppleButton.Style.BLACK}
-        buttonType={AppleButton.Type.SIGN_IN}
-        onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
-      />
+      {
+        appleAuth.isSupported && (
+          <View>
+            <Text style={styles.header}>Credential State</Text>
+            <Text>{credentialStateForUser}</Text>
+
+            <Text style={styles.header}>Buttons</Text>
+            <Text>Continue Styles</Text>
+            <AppleButton
+              style={styles.appleButton}
+              cornerRadius={5}
+              buttonStyle={AppleButton.Style.WHITE}
+              buttonType={AppleButton.Type.CONTINUE}
+              onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
+            />
+            <AppleButton
+              style={styles.appleButton}
+              cornerRadius={5}
+              buttonStyle={AppleButton.Style.WHITE_OUTLINE}
+              buttonType={AppleButton.Type.CONTINUE}
+              onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
+            />
+            <AppleButton
+              style={styles.appleButton}
+              cornerRadius={5}
+              buttonStyle={AppleButton.Style.BLACK}
+              buttonType={AppleButton.Type.CONTINUE}
+              onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
+            />
+            <Text>Sign-in Styles</Text>
+            <AppleButton
+              style={styles.appleButton}
+              cornerRadius={5}
+              buttonStyle={AppleButton.Style.WHITE}
+              buttonType={AppleButton.Type.SIGN_IN}
+              onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
+            />
+            <AppleButton
+              style={styles.appleButton}
+              cornerRadius={5}
+              buttonStyle={AppleButton.Style.WHITE_OUTLINE}
+              buttonType={AppleButton.Type.SIGN_IN}
+              onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
+            />
+            <AppleButton
+              style={styles.appleButton}
+              cornerRadius={5}
+              buttonStyle={AppleButton.Style.BLACK}
+              buttonType={AppleButton.Type.SIGN_IN}
+              onPress={() => onAppleButtonPress(updateCredentialStateForUser)}
+            />
+          </View>
+        )
+      }
+
+      {
+        !appleAuth.isSupported && (
+          <View>
+            <Text>
+              Apple Authentication is not supported on this device.
+            </Text>
+            <Text>
+              But in such cases you can always use apple webView sign in!
+            </Text>
+          </View>
+        )
+      }
+
+      {
+        <TouchableOpacity onPress={
+          () => {
+            setAppleAuthConfig(getAppleAuthConfig());
+          }
+        }>
+          <View style={styles.button}>
+            <Text style={styles.label}>
+              WebView sign in with Apple
+            </Text>
+          </View>
+        </TouchableOpacity>
+      }
     </View>
   );
 }
diff --git a/example/app.shared.js b/example/app.shared.js
new file mode 100644
index 00000000..09efccac
--- /dev/null
+++ b/example/app.shared.js
@@ -0,0 +1,60 @@
+import "react-native-get-random-values";
+import { v4 as uuid } from "uuid";
+
+export function getAppleAuthConfig() {
+
+  // Generate secure, random values for state and nonce
+  const nonce = uuid();
+  const state = uuid();
+
+  // https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms
+  const appleAuthConfig = {
+    // The Service ID you registered with Apple
+    clientId: "com.example.client-web",
+
+    // Return URL added to your Apple dev console. It must still match the URL you provided to Apple.
+    redirectUri: "https://example.com/auth/callback",
+
+    // The type of response requested - code, id_token, or both.
+    responseType: "code id_token",
+
+    // [OPTIONAL]
+    // The amount of user information requested from Apple - code id_token, code, id_token
+    scope: "name email",
+
+    // [OPTIONAL]
+    // Random nonce value that will be SHA256 hashed before sending to Apple.
+    nonce: nonce,
+
+    // [OPTIONAL]
+    // Unique state value used to prevent CSRF attacks. A UUID will be generated if nothing is provided.
+    state: state
+  };
+
+  return appleAuthConfig;
+}
+
+export function parseAppleAuthResponse(responseContent) {
+
+  // Handle your server response (after login - apple redirects to your server url)
+  console.log("parseAppleAuthResponse responseContent", responseContent);
+
+  try {
+
+    // We expecting json response from a server
+    const serverResponse = JSON.parse(responseContent);
+
+    // Next code depents what your server returns on error.
+    // If it is json error pbject then check it.
+    // On success my server return a json with {jwt: "some value"}
+    const jwt = serverResponse.jwt;
+
+    if (jwt) {
+      console.log("parseAppleAuthResponse responseContent jwt", jwt);
+    } else {
+      console.error("parseAppleAuthResponse responseContent does not contain expected jwt");
+    }
+  } catch (error) {
+    console.error("parseAppleAuthResponse responseContent is not a valid json", error);
+  }
+}
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index a6859dcc..0281c8c6 100644
--- a/example/ios/Podfile.lock
+++ b/example/ios/Podfile.lock
@@ -284,6 +284,8 @@ PODS:
     - glog
   - react-native-get-random-values (1.9.0):
     - React-Core
+  - react-native-webview (13.6.2):
+    - React-Core
   - React-NativeModulesApple (0.72.6):
     - React-callinvoker
     - React-Core
@@ -397,7 +399,7 @@ PODS:
     - React-Core
     - React-jsi
   - ReactTestApp-Resources (1.0.0-dev)
-  - RNAppleAuthentication (2.2.2):
+  - RNAppleAuthentication (2.3.0):
     - React-Core
   - SocketRocket (0.6.1)
   - Yoga (1.14.0)
@@ -425,6 +427,7 @@ DEPENDENCIES:
   - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
   - React-logger (from `../node_modules/react-native/ReactCommon/logger`)
   - react-native-get-random-values (from `../node_modules/react-native-get-random-values`)
+  - react-native-webview (from `../node_modules/react-native-webview`)
   - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
   - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
   - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
@@ -496,6 +499,8 @@ EXTERNAL SOURCES:
     :path: "../node_modules/react-native/ReactCommon/logger"
   react-native-get-random-values:
     :path: "../node_modules/react-native-get-random-values"
+  react-native-webview:
+    :path: "../node_modules/react-native-webview"
   React-NativeModulesApple:
     :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios"
   React-perflogger:
@@ -564,6 +569,7 @@ SPEC CHECKSUMS:
   React-jsinspector: 194e32c6aab382d88713ad3dd0025c5f5c4ee072
   React-logger: cebf22b6cf43434e471dc561e5911b40ac01d289
   react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb
+  react-native-webview: 8fc09f66a1a5b16bbe37c3878fda27d5982bb776
   React-NativeModulesApple: 63505fb94b71e2469cab35bdaf36cca813cb5bfd
   React-perflogger: e3596db7e753f51766bceadc061936ef1472edc3
   React-RCTActionSheet: 17ab132c748b4471012abbcdcf5befe860660485
@@ -584,7 +590,7 @@ SPEC CHECKSUMS:
   ReactNativeHost: 5caf8c9381f26c453fabbe8c3b87f6a013a3c459
   ReactTestApp-DevSupport: b1c7adc1c49c50d3bc1cbe7f23191170bdac0319
   ReactTestApp-Resources: 1f512f66574607bcfa614e9c0d30e7a990fecf30
-  RNAppleAuthentication: 0571c08da8c327ae2afc0261b48b4a515b0286a6
+  RNAppleAuthentication: e99eaf3c4c01ad8ecb6125dd6f0cfd98871685b5
   SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
   Yoga: b76f1acfda8212aa16b7e26bcce3983230c82603
 
diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock
index 98635c33..861e216b 100644
--- a/example/macos/Podfile.lock
+++ b/example/macos/Podfile.lock
@@ -284,6 +284,8 @@ PODS:
     - glog
   - react-native-get-random-values (1.9.0):
     - React-Core
+  - react-native-webview (13.6.2):
+    - React-Core
   - React-NativeModulesApple (0.72.5):
     - React-callinvoker
     - React-Core
@@ -397,7 +399,7 @@ PODS:
     - React-Core
     - React-jsi
   - ReactTestApp-Resources (1.0.0-dev)
-  - RNAppleAuthentication (2.2.2):
+  - RNAppleAuthentication (2.3.0):
     - React-Core
   - SocketRocket (0.7.0)
   - Yoga (1.14.0)
@@ -425,6 +427,7 @@ DEPENDENCIES:
   - React-jsinspector (from `../node_modules/react-native-macos/ReactCommon/jsinspector`)
   - React-logger (from `../node_modules/react-native-macos/ReactCommon/logger`)
   - react-native-get-random-values (from `../node_modules/react-native-get-random-values`)
+  - react-native-webview (from `../node_modules/react-native-webview`)
   - React-NativeModulesApple (from `../node_modules/react-native-macos/ReactCommon/react/nativemodule/core/platform/ios`)
   - React-perflogger (from `../node_modules/react-native-macos/ReactCommon/reactperflogger`)
   - React-RCTActionSheet (from `../node_modules/react-native-macos/Libraries/ActionSheetIOS`)
@@ -496,6 +499,8 @@ EXTERNAL SOURCES:
     :path: "../node_modules/react-native-macos/ReactCommon/logger"
   react-native-get-random-values:
     :path: "../node_modules/react-native-get-random-values"
+  react-native-webview:
+    :path: "../node_modules/react-native-webview"
   React-NativeModulesApple:
     :path: "../node_modules/react-native-macos/ReactCommon/react/nativemodule/core/platform/ios"
   React-perflogger:
@@ -564,6 +569,7 @@ SPEC CHECKSUMS:
   React-jsinspector: c25519b0c5b03eaedbb8332f9a42b30a0a3d05fe
   React-logger: 2f13e5bdf0bfe2edc6b0473c4749a96a3a7ac048
   react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb
+  react-native-webview: 8fc09f66a1a5b16bbe37c3878fda27d5982bb776
   React-NativeModulesApple: 91f44f048ff46a6df8c2e9018e3ff79497a5438c
   React-perflogger: 6ccd6df1be652005b9e635df8fae345618466bde
   React-RCTActionSheet: 4adbdcae93457b2b0d146d9fa8ab7c835f661fb6
@@ -584,7 +590,7 @@ SPEC CHECKSUMS:
   ReactNativeHost: 5caf8c9381f26c453fabbe8c3b87f6a013a3c459
   ReactTestApp-DevSupport: b1c7adc1c49c50d3bc1cbe7f23191170bdac0319
   ReactTestApp-Resources: 8539dac0f8d2ef3821827a537e37812104c6ff78
-  RNAppleAuthentication: 0571c08da8c327ae2afc0261b48b4a515b0286a6
+  RNAppleAuthentication: e99eaf3c4c01ad8ecb6125dd6f0cfd98871685b5
   SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
   Yoga: eb938eb0ef4d510b93617486cf6cbe1ad6a94436
 
diff --git a/example/package.json b/example/package.json
index 4bceadf3..7365338f 100644
--- a/example/package.json
+++ b/example/package.json
@@ -18,7 +18,9 @@
     "react": "18.2.0",
     "react-native": "0.72.6",
     "react-native-get-random-values": "^1.9.0",
-    "react-native-macos": "^0.72.0"
+    "react-native-macos": "^0.72.0",
+    "react-native-webview": "^13.6.2",
+    "uuid": "^9.0.1"
   },
   "devDependencies": {
     "@babel/core": "^7.20.0",
diff --git a/example/yarn.lock b/example/yarn.lock
index c1493b30..6451e3d1 100644
--- a/example/yarn.lock
+++ b/example/yarn.lock
@@ -1215,7 +1215,7 @@
   integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==
 
 "@invertase/react-native-apple-authentication@../":
-  version "2.2.2"
+  version "2.3.0"
 
 "@istanbuljs/load-nyc-config@^1.0.0":
   version "1.1.0"
@@ -3022,16 +3022,16 @@ escape-html@~1.0.3:
   resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
   integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
 
+escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
+  integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
+
 escape-string-regexp@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
   integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
 
-escape-string-regexp@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
-  integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
-
 escape-string-regexp@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
@@ -3727,7 +3727,7 @@ internal-slot@^1.0.5:
     hasown "^2.0.0"
     side-channel "^1.0.4"
 
-invariant@*, invariant@^2.2.4:
+invariant@*, invariant@2.2.4, invariant@^2.2.4:
   version "2.2.4"
   resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
   integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
@@ -5564,6 +5564,14 @@ react-native-test-app@^2.5.32:
     semver "^7.3.5"
     uuid "^8.3.2"
 
+react-native-webview@^13.6.2:
+  version "13.6.2"
+  resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-13.6.2.tgz#0a9b18793e915add5b5dbdbf32509d7751b49167"
+  integrity sha512-QzhQ5JCU+Nf2W285DtvCZOVQy/MkJXMwNDYPZvOWQbAOgxJMSSO+BtqXTMA1UPugDsko6PxJ0TxSlUwIwJijDg==
+  dependencies:
+    escape-string-regexp "2.0.0"
+    invariant "2.2.4"
+
 react-native@0.72.6:
   version "0.72.6"
   resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.72.6.tgz#9f8d090694907e2f83af22e115cc0e4a3d5fa626"
@@ -6473,6 +6481,11 @@ uuid@^8.3.2:
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
   integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
 
+uuid@^9.0.1:
+  version "9.0.1"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
+  integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
+
 v8-to-istanbul@^9.0.1:
   version "9.1.3"
   resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b"
diff --git a/lib/AppleAuthWebView.js b/lib/AppleAuthWebView.js
new file mode 100644
index 00000000..48d91e79
--- /dev/null
+++ b/lib/AppleAuthWebView.js
@@ -0,0 +1,282 @@
+import React from "react";
+import {
+  View,
+  ActivityIndicator
+} from "react-native";
+import {
+  WebView
+} from "react-native-webview";
+
+export default class AppleAuthWebView extends React.PureComponent {
+  constructor(props) {
+    super(props);
+
+    const me = this;
+    const onResponse = props.onResponse;
+    const config = props.config; // || (props.route && props.route.params && props.route.params.config);
+    const loadingIndicator = props.loadingIndicator;
+    const clientId = config.clientId;
+    const redirectUri = config.redirectUri;
+    const scope = config.scope;
+    const responseType = config.responseType;
+    const state = config.state;
+    const rawNonce = config.rawNonce;
+    const nonce = config.nonce;
+
+    // Input data validating
+    // https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms#3332113
+    if (typeof onResponse !== "function") {
+      throw new Error(
+        "AppleAuthWebView.constructor 'onResponse' is required and must be a function."
+      );
+    }
+
+    if (loadingIndicator && typeof loadingIndicator !== "function") {
+      throw new Error(
+        "AppleAuthWebView.constructor 'loadingIndicator' required as a function, if provided."
+      );
+    }
+
+    if (typeof config !== "object") {
+      throw new Error(
+        "AppleAuthWebView.constructor 'config' is required and must be an object."
+      );
+    } else {
+      if (typeof clientId !== "string") {
+        throw new Error(
+          "AppleAuthWebView.constructor 'clientId' is required and must be a string."
+        );
+      }
+
+      if (typeof redirectUri !== "string") {
+        throw new Error(
+          "AppleAuthWebView.constructor 'redirectUri' is required and must be a string."
+        );
+      }
+
+      if (typeof scope !== "string") {
+        throw new Error(
+          "AppleAuthWebView.constructor 'scope' is required and must be a string."
+        );
+      } else if (
+        scope !== "name" &&
+        scope !== "email" &&
+        scope !== "name email"
+      ) {
+        throw new Error(
+          "AppleAuthWebView.constructor 'scope' is invalid. Possible values 'name', 'email', 'name email'"
+        );
+      }
+
+      if (responseType && typeof responseType !== "string") {
+        throw new Error(
+          "AppleAuthWebView.constructor 'responseType' required as a string, if provided."
+        );
+      }
+
+      if (
+        responseType &&
+        responseType !== "code" &&
+        responseType !== "id_token" &&
+        responseType !== "code id_token"
+      ) {
+        throw new Error(
+          "AppleAuthWebView.constructor 'responseType' is invalid. Possible values 'code', 'id_token', 'code id_token'"
+        );
+      }
+
+      if (state && typeof state !== "string") {
+        throw new Error(
+          "AppleAuthWebView.constructor 'state' required as a string, if provided."
+        );
+      }
+
+      if (rawNonce && typeof rawNonce !== "string") {
+        throw new Error(
+          "AppleAuthWebView.constructor 'rawNonce' required as a string, if provided."
+        );
+      }
+
+      if (nonce && typeof nonce !== "string") {
+        throw new Error(
+          "AppleAuthWebView.constructor 'nonce' required as a string, if provided."
+        );
+      }
+    }
+
+    me.state = {
+      config: config,
+      isAppleInitialWebPageLoading: false,
+      isRedirectResultContentLoading: false
+    };
+
+    me.appleDirectAuthorizationUrl = "https://appleid.apple.com/auth/authorize";
+  }
+
+  onNavigationStateChange = (navigationState) => {
+    const me = this;
+    const url = navigationState.url;
+    const loading = navigationState.loading;
+    const appleAuthUrl = me.appleDirectAuthorizationUrl;
+
+    if (
+      url.substr(0, appleAuthUrl.length) === appleAuthUrl &&
+      loading !== me.state.isAppleInitialWebPageLoading
+    ) {
+      me.setState(
+        {
+          isAppleInitialWebPageLoading: loading
+        }
+      );
+
+      return;
+    }
+
+    // Loading redirected page
+    const redirectUri = me.state.config.redirectUri;
+
+    if (
+      url.substr(0, redirectUri.length) === redirectUri &&
+      !me.state.isAppleInitialWebPageLoading
+    ) {
+      me.setState(
+        {
+          isRedirectResultContentLoading: true // To hide our server response
+        }
+      );
+
+      me.webview.injectJavaScript(
+        `
+          function checkContent() {
+            if (document && document.documentElement) {
+              window.ReactNativeWebView.postMessage(
+                JSON.stringify(
+                  {
+                    href: window.location.href,
+                    pageContent: document.documentElement.innerText
+                  }
+                )
+              );
+            } else {
+              setTimeout(
+                function () {
+                  checkContent();
+                },
+                300
+              );
+            }
+          }
+
+          checkContent();
+          true;
+        `
+      );
+    }
+  }
+
+  onMessageFromRedirectedPage = (event) => {
+    const me = this;
+    const message = event.nativeEvent.data;
+
+    try {
+      const data = JSON.parse(message);
+      const redirectUri = me.state.config.redirectUri;
+
+      if (data.href.substr(0, redirectUri.length) === redirectUri) {
+        me.props.onResponse(data.pageContent);
+      }
+    } catch (error) {
+      console.error("AppleAuthWebView.onMessageFromRedirectedPage Cannot parse web page message.", message);
+    }
+  }
+
+  /**
+   * Build an Apple URL that supports `form_post`
+   * Incorporating Sign in with Apple into Other Platforms
+   * https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms.
+   */
+  getDirectAuthorizationSourceUri = (config) => {
+    const me = this;
+    const scope = config.scope;
+    const state = config.state;
+    const nonce = config.nonce;
+
+    return {
+      uri: me.appleDirectAuthorizationUrl +
+        "?client_id=" + encodeURIComponent(config.clientId) +
+        "&redirect_uri=" + encodeURIComponent(config.redirectUri) +
+        "&response_type=" + encodeURIComponent(config.responseType) +
+        (scope ? "&scope=" + encodeURIComponent(scope) : "") +
+        "&response_mode=form_post" +
+        (state ? "&state=" + encodeURIComponent(state) : "") +
+        (nonce ? "&nonce=" + encodeURIComponent(nonce) : "")
+    };
+  }
+
+  onComponentRefenceReady = (ref) => {
+    const me = this;
+
+    me.webview = ref;
+    // me.webview.stopLoading();
+    // me.webview.injectJavaScript(redirectTo);
+  }
+
+  render() {
+    const me = this;
+    const state = me.state;
+    const isLoading = state.isAppleInitialWebPageLoading || state.isRedirectResultContentLoading;
+
+    return (
+      <View style={{
+        flex: 1
+      }}>
+        {
+          (
+            <WebView
+              // Android 9: App crashes if hardware acceleration is enabled
+              // https://github.com/react-native-webview/react-native-webview/issues/575
+              androidHardwareAccelerationDisabled={true}
+              ref={me.onComponentRefenceReady}
+              source={me.getDirectAuthorizationSourceUri(state.config)}
+              onNavigationStateChange={me.onNavigationStateChange}
+              javaScriptEnabled={true}
+              onMessage={me.onMessageFromRedirectedPage}
+            />
+          )
+        }
+
+        {
+          isLoading && (
+            me.props.loadingIndicator ? (
+              <View style={{
+                position: "absolute",
+                top: 0,
+                left: 0,
+                bottom: 0,
+                right: 0
+              }}>
+                {
+                  me.props.loadingIndicator()
+                }
+              </View>
+            ) : (
+              <ActivityIndicator
+                size="large"
+                animating
+                style={{
+                  position: "absolute",
+                  left: 0,
+                  right: 0,
+                  top: 0,
+                  bottom: 0,
+                  alignItems: "center",
+                  justifyContent: "center"
+                }}
+              />
+            )
+          )
+        }
+      </View>
+    );
+  }
+}
diff --git a/lib/index.js b/lib/index.js
index aae53935..5287ea64 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -18,6 +18,7 @@
 import version from './version';
 import { NativeModules } from 'react-native';
 import AppleAuthModule from './AppleAuthModule';
+import AppleAuthWebView from './AppleAuthWebView';
 const { RNAppleAuthModule, RNAppleAuthModuleAndroid } = NativeModules;
 
 
@@ -45,3 +46,8 @@ export const appleAuthAndroid = RNAppleAuthModuleAndroid ? {
   Scope: RNAppleAuthModuleAndroid.Scope,
   ResponseType: RNAppleAuthModuleAndroid.ResponseType,
 } : {};
+
+/**
+ * WebView
+ */
+export { default as AppleAuthWebView } from './AppleAuthWebView';