> ## Documentation Index
> Fetch the complete documentation index at: https://www.marqeta.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with UX Toolkit within Native Webviews

> Instructions on how to use UX Toolkit web components and two-way communication to configure and interact with webviews.

Marqeta’s [UX Toolkit web components use iframes](/developer-guides/about-ux-toolkit/#_dynamic_card_data_iframes) to ensure customers' web applications [maintain PCI compliance](/developer-guides/about-ux-toolkit/#_data_security_compliance), without requiring customers to be compliant themselves. The iframes at the core of UX Toolkit web components simplify using UX Toolkit web components in native webviews. You can use the UX Toolkit iframe HTML file URL—`UXT_WEBVIEW_SRC`—as the source for all webviews and leverage two-way communication via `postMessage()` to configure and interact with them.

<Note>
  **Note**\
  You can display multiple UX Toolkit components on a single screen by rendering a webview for each component. To manage this webview logic, you may opt to create a new component within your application platform, making it simpler to repeat without interfering with other webviews.
</Note>

<Warning>
  **Important**\
  This version of UX Toolkit supports prepaid and debit card programs in the United States, Canada, and the EU.
</Warning>

<h2 id="_authentication">
  Authentication
</h2>

To authenticate webviews, follow the authentication flow as described in [UX Toolkit Getting Started](/developer-guides/uxt-getting-started/#_authentication_workflow). However, for webviews, you must use the `apiHeadersResolver` property to pass required authentication bearer tokens or session tokens generated from your platform for your application. To see an example of how to pass `apiHeadersResolver`, see the code example in the [About the window.postMessage() method](/developer-guides/uxt-within-native-webviews/#_about_the_window_postmessage_method) section below.

<Note>
  **Note**\
  You must configure Cross-Origin Resource Sharing (CORS) on your authentication endpoint to allow `POST` and `OPTIONS` requests from "[https://web.ux-toolkit.marqeta.com](https://web.ux-toolkit.marqeta.com)". Webview implementations fail without this configuration.
</Note>

<h2 id="_sending_post_messages">
  Sending post messages
</h2>

When initiating your webview and UX Toolkit component, a `window.postMessage()` JavaScript call needs to be injected into the webview.

Key considerations for sending post messages from your native application to the UX Toolkit component inside the webview are outlined in the following section.

<h3 id="_about_post_messages">
  About post messages
</h3>

JavaScript and Document Object Model (DOM) Storage must be enabled in order to use UX Toolkit components within webviews.

Be aware that webview’s content size may change. For details, see [Capturing resize events](/developer-guides/uxt-within-native-webviews/#_capturing_resize_events).

<h4 id="_about_the_window_postmessage_method">
  About the window\.postMessage() method
</h4>

The `message` property of the `window.postMessage()` method must be `setProps`.

The `globalProps` property contains:

| Field                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authParams`           | This object contains the following elements:<br /><br />- `apiEndpoint` (Required): The string value of a fully-qualified URL representing your authentication API endpoint. For more information about authentication, see <a href="/developer-guides/uxt-getting-started/#_authentication_workflow">Authentication workflow</a>.<br />- `apiHeadersResolver` (Optional): This object is used to pass any session or auth token headers to your authentication API endpoint for the purpose of authenticating users with your application. |
| `componentName`        | The string value of any component available to your program, as listed in <a href="https://studio.ux-toolkit.marqeta.com" target="_blank" rel="noopener">Studio</a>. Component names must be in provided in kebab case.                                                                                                                                                                                                                                                                                                                     |
| `envName`              | (Optional) Indicates which environment is being targeted. Allowable values for this field are `sandbox` or `production`. The default value for this field is `production`.                                                                                                                                                                                                                                                                                                                                                                  |
| `postMessageAgentName` | The string value for the `postMessage()` agent name. For details, see <a href="/developer-guides/uxt-within-native-webviews/#_receiving_post_messages">Receiving post messages</a>.                                                                                                                                                                                                                                                                                                                                                         |
| `themeName`            | (Optional) The name of an existing theme that was created using the `/theme` endpoint. The default value of this field is `default`. For more information on the `/theme` endpoint, see <a href="/core-api/uxt-sdk/#post_theme_by_name">Upload theme object</a>.                                                                                                                                                                                                                                                                            |

The `componentProps` property contains the necessary properties and attributes for the component, as listed in [Studio](https://studio.ux-toolkit.marqeta.com). All kebab case HTML component properties, such as `kebab-case-property`, must be converted to lower camel case (e.g., `lowerCamelCase`) when passed to `componentProps`.

The final argument in the `window.postMessage()` must be the valid base URL. If the base URL does not match the webview source hostname, the call to `window.postMessage()` will fail.

The following example uses React-Native:

```javascript JavaScript expandable lines wrap theme={null}
const UXT_CDN_BASE_URL = 'https://web.ux-toolkit.marqeta.com';
const SHORT_CODE = 'YOUR_PROGRAM_SHORT_CODE';
const UXT_WEBVIEW_SRC = `${UXT_CDN_BASE_URL}/${SHORT_CODE}/releases/1/www/iframe-page-root/index.html`;
let webview1: WebView | null = null;
return (
  <WebView
    ref={(ref) => (webview1 = ref)}
    originWhitelist={['*']}
    source={{ uri: UXT_WEBVIEW_SRC }}
    javaScriptEnabled={true}
    domStorageEnabled={true}
    showsVerticalScrollIndicator={false}
    style={{ height: '240px' }}
    onLoadEnd={() => {
      webview1?.injectJavaScript(`
        window.postMessage(
          {
            message: 'setProps',
            globalProps: {
              authParams: {
                apiEndpoint: 'https://your-domain/api/auth',
                apiHeadersResolver: {
                  'Authorization': 'Bearer SOME-AUTH-TOKEN-HERE'
                  }
              },
              envName: 'sandbox',
              themeName: 'your-theme-name-here',
              componentName: 'mq-card',
              postMessageAgentName: 'ReactNativeWebView',
            },
            componentProps: {
              cardToken: 'fd076080-0568-409d-8fc0-af1159a1826d',
              canChangeSides: true,
            },
          },
          '${UXT_CDN_BASE_URL}',
        );
      `);
    }}
  />
);
```

<h2 id="_receiving_post_messages">
  Receiving post messages
</h2>

Receiving messages from inside the webview is similar to sending them. However, there are differences across the native platforms—React-Native, iOS, Android, and Flutter. Every platform contains a post message agent or object with a `postMessage(message: string): void` method called by the UX Toolkit component. This is the method by which the events listed in [Studio](https://studio.ux-toolkit.marqeta.com) are passed to your native application. Each platform has a predefined convention for the locations of the `postMessage()` methods. Note that the string value which is passed to `postMessage()` is a string-encoded JSON object.

You can seamlessly integrate behaviors between two UX Toolkit components and webviews. For example, if you have the `mq-card` and `mq-card-actions` on the same screen, you can listen for the respective message on the `mq-card-actions` component when a card is locked, and you can then refresh the `mq-card` webview to reflect the new changes. When you refresh a webview, you must repost the initialization message as described in [Sending post messages](/developer-guides/uxt-within-native-webviews/#_sending_post_messages).

For React-Native, iOS, Android, and Flutter platforms, the agent/object is referenced within JavaScript’s `window` object. However, the name of the agent/object varies. Use the `postMessageAgentName` property to specify the location of the agent/object as follows:

| Platform     | Agent/Object                                                    | Post Message Agent Name                    | Post Message Resource                                                                                                                                                                                                                                                                         |
| ------------ | --------------------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| React-Native | `window.ReactNativeWebView.postMessage()`                       | `ReactNativeWebView`                       | <a href="https://github.com/react-native-webview/react-native-webview/blob/master/docs/Guide.md#the-windowreactnativewebviewpostmessage-method-and-onmessage-prop" target="_blank" rel="noopener">React-Native implementation</a>                                                             |
| iOS          | `window.webkit.messageHandlers.YOUR_HANDLER_NAME.postMessage()` | `webkit.messageHandlers.YOUR_HANDLER_NAME` | <a href="https://diamantidis.github.io/2020/02/02/two-way-communication-between-ios-wkwebview-and-web-page#adding-the-message-handler" target="_blank" rel="noopener">iOS implementation</a>                                                                                                  |
| Android      | `window.YOUR_HANDLER_NAME.postMessage()`                        | `YOUR_HANDLER_NAME`                        | <a href="https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E,androidx.webkit.WebViewCompat.WebMessageListener)" target="_blank" rel="noopener">Android implementation</a> |
| Flutter      | `window.YOUR_HANDLER_NAME.postMessage()`                        | `YOUR_HANDLER_NAME`                        | <a href="https://inappwebview.dev/docs/webview/javascript/communication/#web-message-listeners" target="_blank" rel="noopener">Flutter implementation</a>                                                                                                                                     |

The following example uses React-Native:

```javascript JavaScript lines wrap theme={null}
const UXT_CDN_BASE_URL = 'https://web.ux-toolkit.marqeta.com';
const UXT_WEBVIEW_SRC = `${UXT_CDN_BASE_URL}/VALID_PROGRAM_SHORT_CODE/releases/1/www/iframe-page-root/index.html`;

let webview1: WebView | null = null;

return (
  <WebView
    ref={(ref) => (webview1 = ref)}
    originWhitelist={['*']}
    source={{ uri: UXT_WEBVIEW_SRC }}
    ... // truncated props for longevity sake
    onMessage={(event) => {
      // remember: the event data is passed as a JSON string and needs to be parsed
      const data = JSON.parse(event.nativeEvent.data);
      console.log('Received from WebView1:', data);
    }}
  />
);
```

<h2 id="_capturing_resize_events">
  Capturing resize events
</h2>

Webviews and UX Toolkit web components are generally responsive by default to viewport changes, such as orientation adjustments. "Viewport" refers to the part of the screen that is being viewed. There are scenarios where the contents of the webview may grow or shrink in height, and the webview is not likely to self-adjust accordingly. In such cases, an event message is triggered when the height of the content changes, giving you the opportunity to adjust the height of the webview.

The following example uses React-Native:

```javascript JavaScript expandable lines wrap theme={null}
const UXT_CDN_BASE_URL = 'https://web.ux-toolkit.marqeta.com';
const UXT_WEBVIEW_SRC = `${UXT_CDN_BASE_URL}/VALID_PROGRAM_SHORT_CODE/releases/1/www/iframe-page-root/index.html`;

let webview1: WebView | null = null;
const [webview1Height, setWebview1Height] = useState(240);

return (
  <WebView
    ref={(ref) => (webview1 = ref)}
    originWhitelist={['*']}
    source={{ uri: UXT_WEBVIEW_SRC }}
    style={{ height: webview1Height }}
    ... // truncated props for longevity sake
    onMessage={(event) => {
      const data = JSON.parse(event.nativeEvent.data);
      const { eventName, height } = data;

      if (eventName === 'iframeBodyResize') {
        setWebview1Height(height);
      }
    }}
  />
);
```
