> For the complete documentation index, see [llms.txt](https://kbase.whitelabel-loyalty.com/developer/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kbase.whitelabel-loyalty.com/developer/guides/deploy-a-loyalty-microsite/embed-a-microsite-in-a-website-or-app.md).

# Embed a microsite in a website or app

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><p><i class="fa-sidebar">:sidebar:</i></p><p><strong>Embed in a website (iframe)</strong></p></td><td><a href="/pages/PkVcFtzfZSz2vsNVJIsM#embed-in-a-website">/pages/PkVcFtzfZSz2vsNVJIsM#embed-in-a-website</a></td></tr><tr><td><p><i class="fa-mobile">:mobile:</i></p><p><strong>Embed in a mobile app (WebView)</strong></p></td><td><a href="/pages/PkVcFtzfZSz2vsNVJIsM#embed-in-a-mobile-app-webview">/pages/PkVcFtzfZSz2vsNVJIsM#embed-in-a-mobile-app-webview</a></td></tr></tbody></table>

***

## Embed in a website (iframe)

Embedding the Loyalty Microsite in a website via an iFrame provides a seamless way to integrate WLL’s loyalty features directly into an existing webpage, allowing users to interact with the loyalty program without leaving your site. Here’s how to set up and configure the microsite in an iFrame.

{% hint style="info" %}
For a sample iFrame implementation, see our [embedding example on GitHub](https://github.com/white-label-loyalty/microsite-web-example).
{% endhint %}

### Handling user authentication

{% hint style="info" %}
This step is only required if you are using **embedded authentication** to allow users to access the microsite without additional login steps.
{% endhint %}

1. **Requesting a Session Token:** Make a secure HTTP request from your server to the microsite’s authentication endpoint, as outlined in [Authenticate users in a microsite](/developer/guides/deploy-a-loyalty-microsite/authenticate-users-in-a-microsite.md). This ensures that your “Client ID” remains protected.
2. **Passing the Session Token:** Pass the returned session token to the microsite within the iFrame by using **a session query parameter** or **as a session cookie**.

#### Using a session query parameter

Append the microsite URL with `?session=$sessionToken`.

#### Using cookies

If using cookies, ensure the user’s browser receives the session cookie before loading the iFrame:

* **From the browser context:** The endpoint will automatically set the cookie.
* **From the server context:** The “Set-Cookie” header in your response should forward to the browser, or you can construct the cookie as explained in [Authenticate users in a microsite](/developer/guides/deploy-a-loyalty-microsite/authenticate-users-in-a-microsite.md).

{% hint style="warning" %}
To ensure authentication functions correctly across all browsers, ensure the [custom domain](/developer/guides/deploy-a-loyalty-microsite/configure-a-microsite-domain.md) configured for your microsite matches that of the webpage hosting the iFrame.
{% endhint %}

### Configuring the iFrame

Add an iFrame element on your webpage pointing to the microsite’s root URL, for example:

{% code overflow="wrap" %}

```html
<iframe src="https://microsite.url.com"></iframe>
```

{% endcode %}

#### iFrame permissions

To enable location services (for reward redemption and receipt upload) and clipboard access (to allow one click copy of voucher and referral codes, and receipt upload email address), add the following attributes to the `<iframe>` tag:

{% code overflow="wrap" %}

```html
allow="clipboard-write self https://microsite.url.com; geolocation self https://microsite.url.com;"
```

{% endcode %}

#### iFrame postMessage communication

When embedded in an iFrame, the Loyalty Microsite uses the [**postMessage()**](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) feature to communicate with the iFrame parent window. You can use these messages to respond to navigation changes or dynamically adjust the iFrame’s height.

<details>

<summary>NAVIGATION message</summary>

Sent when a user navigates within the microsite. Contains the `type`, `url`, and `contentHeight` properties.

{% code title="Message example" %}

```json
{
  type: "NAVIGATION",
  url: "https://example.com",
  contentHeight: 1000,
}
```

{% endcode %}

</details>

<details>

<summary>RESIZE_BODY message</summary>

Sent when the height of the microsite content changes. Contains the `type` and `contentHeight` properties.

{% hint style="info" %}
The `contentHeight` value represents the height of the microsite content in pixels, specifically derived from the *`window.document.body.scrollHeight`* property. This allows the iFrame to dynamically adjust its height based on the actual content height within the microsite, ensuring smooth user experience without scrollbars.
{% endhint %}

{% code title="Message example" %}

```json
{
  type: "RESIZE_BODY",
  contentHeight: 1000,
}
```

{% endcode %}

{% code title="Example implementation for resizing the iFrame" overflow="wrap" lineNumbers="true" %}

```javascript
function receiveMessage(event) {
  // must check that the message origin is legitimate
  if (!event.origin.endsWith("https://HOSTDOMAIN.COM")) {
    // return immediately to prevent further processing
    return console.info(
      "Received a potentially malicious message from an unexpected origin",
      event.origin
    );
  }

  if (event.data.type === "NAVIGATION") {
    var eFrame = document.getElementById("REPLACE_WITH_HTML_ID_ATTACHED_TO_YOUR_IFRAME_ELEMENT");
    window.scrollTo(0, 0);
    eFrame.height = event.data.contentHeight + event.data.contentHeight * 0.2;
  }
}

window.addEventListener("message", receiveMessage, false);
```

{% endcode %}

</details>

### Website embed FAQs

#### Is it possible to load specific pages of the microsite directly in an iFrame?

Yes, you can add URL parameters to load specific microsite pages. For example, to load the Activity page, modify the iFrame src URL to include `redirect_path=/activity` (e.g., `https://MICROSITEURL.COM?redirect_path=/activity`).

#### What if my iFrame content height changes dynamically?

Use the postMessage() feature to handle dynamic height changes. The microsite sends a `RESIZE_BODY` message when the content height changes, allowing your iFrame to adjust its height based on the contentHeight value provided.

***

## Embed in a mobile app (WebView)

Embedding the Loyalty Microsite in a mobile app enables your loyalty program to integrate directly with your app’s user interface, providing a smooth experience without needing a deep-level API integration.

To configure a mobile WebView for the Loyalty Microsite, complete the following key steps:

1. Set up the correct permissions for the app’s platform (iOS or Android).
2. Ensure necessary UI handlers, such as dialogs and file access, are supported.
3. Pass the generated session token within the WebView request.
4. Load the appropriate URL based on the user’s locale.

The root URL to load within the WebView is the [custom domain](/developer/guides/deploy-a-loyalty-microsite/configure-a-microsite-domain.md) your microsite lives on.

{% tabs %}
{% tab title="iOS" %}

## iOS configuration

### Permissions

Add the following permissions to the Info.plist to ensure correct functionality. Camera and photo permissions are needed if using receipt scanning.

```xml
<dict>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    <key>NSCameraUsageDescription</key>
    <string>Camera access required to scan receipts.</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Location verification needed for voucher redemption.</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>Photo library access required to select receipt photos.</string>
</dict>
```

### UI handlers

The view controller housing the WebView should implement the WKUIDelegate protocol to handle native confirmation dialogs:

```swift
func webView(_ webView: WKWebView,
                 runJavaScriptConfirmPanelWithMessage message: String,
                 initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping (Bool) -> Void) {
        let alertController = UIAlertController(title: message,
                                                message: nil,
                                                preferredStyle: .alert)

        alertController.addAction(UIAlertAction(title: "OK",
                                                style: .default,
                                                handler: { (action) in
            completionHandler(true)
        }))

        alertController.addAction(UIAlertAction(title: "Cancel",
                                                style: .cancel,
                                                handler: { (action) in
            completionHandler(false)
        }))

        present(alertController, animated: true, completion: nil)
    }
```

{% endtab %}

{% tab title="Android" %}

## Android configuration

### Permissions

Include the following permissions in the Android manifest. Camera and photo permissions are required if you plan to enable receipt scanning.

```markup
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
```

### UI handlers

The Android WebView configuration requires additional setup. Refer to the example configuration in this [repository](https://github.com/white-label-loyalty/microsite-web-example) for detailed setup instructions.\
\
Additionally you may also need to enable Javascript and DOM storage for the WebView in order for the microsite to function properly :&#x20;

```java
// Let the web view use JavaScript.
webView.getSettings().setJavaScriptEnabled(true);
// Let the web view access local storage.
webView.getSettings().setDomStorageEnabled(true)
```

{% endtab %}
{% endtabs %}

***

## Language support

The Loyalty Microsite supports multiple languages, enabling you to offer a localized experience to your users. You can set a default language in the microsite settings, but you can specify a different language using the `?lang=` parameter in the URL.

Currently, supported languages include **French (fr)**, **German (de)**, and **Italian (it)**.

To load the microsite in French, for example, you would use the URL format: `https://MICROSITEURL.COM?lang=fr`

{% hint style="info" %}
If you plan to deploy your microsite in a language other than English, please consult WLL Support to ensure proper configuration. See [4. Language support](https://kbase.whitelabel-loyalty.com/product/interfaces/white-label-interfaces/loyalty-microsite/loyalty-microsite-setup/4.-language-support) for more information.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://kbase.whitelabel-loyalty.com/developer/guides/deploy-a-loyalty-microsite/embed-a-microsite-in-a-website-or-app.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
