# How to Integrate the Widget into a Mobile App (WebView)

The ConnectiveOne widget can be embedded in a mobile app via WebView. This allows you to display chatbots and operator connections directly in iOS, Android, or React Native apps. This guide helps you get the widget URL and integrate it on each platform.

## When You Need This

- You need to add ConnectiveOne chat to a native mobile app (iOS, Android).
- You are building a React Native app and want to display the widget on a screen.
- You have a widget on a website and want to use the same chat in a mobile app.

## Key Concepts

- **WebView** — a component that displays web content inside an app. On iOS it's WKWebView, on Android — WebView, in React Native — the react-native-webview library.
- **Widget URL** — the URL of a page where the widget is opened in Frame format. This URL is loaded in the WebView.
- **Frame format** — a widget display mode (Full screen mode) selected in Widget Demo. The widget fills the entire container and is suitable for WebView.

## Prerequisites

- [x] You have an active bot in ConnectiveOne with a configured widget.
- [x] You have access to widget settings (Menu → Settings → Bots → select bot → Widget).
- [x] You have a development environment: Xcode (iOS), Android Studio (Android), or Node.js with React Native.
- [x] You have obtained the widget URL in Frame format (see section below).

---

## How to Get the Widget URL

Before integrating into a mobile app, you need to obtain the widget URL in Frame format.

1. Open **Widget Demo** — the widget appearance settings page (path: `/widget/{locale}/?bot-id={bot_id}` or via Menu → Settings → Bots → select bot → go to Widget Demo).
2. In the left settings panel, select **Frame** mode (Full screen mode).
3. Copy the generated embed code and add it to an empty web page. Publish the page on a domain you control.
4. Go to **Menu** → **Settings** → **Bots** → select bot → **Widget** and add your page **origin** (for example, `https://your-app.example.com`) to the allowed domains list.
5. The URL of the published page is your WebView URL. Use it instead of the examples in the code below.

---

## iOS (Swift)

For iOS, use **WKWebView**. You need a Mac and Xcode.

### Step 1. Create a Project

1. Open Xcode → **File** → **New** → **Project**.
2. Select **iOS** → **Single View App** → **Next**.
3. Enter Product Name and Organization Identifier → **Create**.

### Step 2. Configure ViewController

Open `ViewController.swift` and replace the code with:

```swift
import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {
    private var webView: WKWebView!

    override func loadView() {
        webView = WKWebView()
        webView.navigationDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        setupWebView()
    }

    private func setupWebView() {
        let config = webView.configuration
        config.allowsInlineMediaPlayback = true  // required for correct behavior

        if let url = URL(string: "YOUR_WIDGET_URL") {
            webView.load(URLRequest(url: url))
        }
    }
}
```

Replace `YOUR_WIDGET_URL` with the URL obtained in the previous section.

### Step 3. Run the App

Build the project and run it in the simulator or on a device.

---

## Android (Kotlin)

For Android, use **WebView** with JavaScript enabled. You need Android Studio.

### Step 1. Prepare MainActivity

In `MainActivity.kt` (or `MainActivity.java`), add a WebView with JavaScript enabled:

```kotlin
// Example with Jetpack Compose
@Composable
fun WebViewPage(url: String) {
    var backEnabled by remember { mutableStateOf(false) }
    var webView: WebView? = null
    val activity = LocalContext.current as Activity

    AndroidView(
        factory = {
            WebView(it).apply {
                settings.javaScriptEnabled = true
                settings.loadWithOverviewMode = true
                settings.useWideViewPort = true
                settings.setSupportZoom(true)
                webViewClient = WebViewClient()
                setWebChromeClient(WebChromeClient())
                loadUrl(url)
                webView = this
            }
        },
        update = { webView = it }
    )

    BackHandler(enabled = backEnabled) {
        webView?.goBack()
    }
}
```

Replace `url` with your widget URL.

### Step 2. Add Permissions to AndroidManifest.xml

Ensure `AndroidManifest.xml` includes the internet permission:

```xml
<uses-permission android:name="android.permission.INTERNET" />
```

### Step 3. Run the App

Build and run the app in the emulator or on a device.

---

## React Native

For React Native, use the **react-native-webview** library.

### Step 1. Install the Library

```bash
npm install react-native-webview
```

### Step 2. Create the Component

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

const FullScreenWebView = () => {
  return (
    <View style={styles.container}>
      <StatusBar barStyle="dark-content" />
      <WebView
        style={styles.webview}
        source={{ uri: 'YOUR_WIDGET_URL' }}
      />
    </View>
  );
};

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

export default FullScreenWebView;
```

Replace `YOUR_WIDGET_URL` with the URL obtained in the "How to Get the Widget URL" section.

### Step 3. Use the Component

Add `FullScreenWebView` to the desired screen in your app.

---

## What Happens After

After integration, the widget is displayed in the mobile app. Users can open the chat, send messages, and receive responses from the bot or operators just as on the website.

## How to Verify It Works

- Open the WebView screen in the app.
- Verify the widget loads (you see the chat interface).
- Tap the widget, send a test message, and confirm you receive a response.
- On Android: for sending files from the chat, additional `WebChromeClient.onShowFileChooser` configuration is required — see Android WebView documentation.
- On iOS: ensure video and audio play correctly (thanks to `allowsInlineMediaPlayback`).

## Related Guides

- [Connect widget to website](/en/channels/how-to/widget/setup-widget-on-website.md)
- [What is a widget](/en/channels/explanation/what-is-widget.md)
- [Configure widget in Settings](/en/channels/how-to/widget/configure-widget-settings.md)
- [Pass parameters from website to scenario](/en/channels/how-to/widget/pass-parameters-from-widget.md)
