> ## Documentation Index
> Fetch the complete documentation index at: https://help.wotnot.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Mobile App

> Deploy your AI agents natively inside your Android or iOS mobile application.

You can integrate WotNot using one of three approaches:

* **Android SDK** — provides a native chat experience for Android apps.
* **iOS SDK** — provides a native chat experience for iOS apps.
* **Webview** — loads the WotNot chatbot inside a webview and is generally the quickest option to deploy.

> [!NOTE]
>
> **Developer required:** Mobile app deployment requires development work. If you do not have access to an Android or iOS developer, use the **Webview** approach, which requires less native integration work.

# Choosing an approach

| Approach | What it takes to implement | What it gives you | When to pick it |
| :- | :- | :- | :- |
| **Android SDK** | Add the WotNot SDK to your Android project and initialize it with your WotNot credentials. | Native Android chat experience with SDK-level configuration and customization. | Choose this when you need tighter integration with an Android app. |
| **iOS SDK** | Add the WotNot SDK using Swift Package Manager and initialize it in your iOS application. | Native iOS chat experience with SwiftUI/UIKit support and theme customization. | Choose this when you need a native iOS experience. |
| **Webview** | Create a web page containing the WotNot chatbot and load it inside your app's webview. | Faster implementation with less native SDK work. | **Recommended for a first deployment** or when you want to ship the chatbot quickly. |

If you are unsure which option to use, start with **Webview**. Move to a native SDK when you need deeper integration with your mobile application's native experience.

# **Webview**

WotNot allows you to embed your chatbot inside your Android/iOS application as a web view.

> [!NOTE]
>
> Native SDKs are being worked on and are not available at the moment.
>
> To request for SDK, email us at **[hello@wotnot.io](mailto:hello@wotnot.io)**

### Getting the URL

To display the chatbot in a web view inside your application, you need to create a new page and embed the chatbot code snippet.

* Open the bot you want to deploy.
* Click the **three-dot menu** on the bot card.
* Select **Embed**.
* Copy the **chatbot-hosted URL** or **embed code**.
  * Use the chatbot bubble or an iframe depending on how you want the chatbot to appear inside your mobile application.
* Create a screen in your mobile application that contains a **webview**.
* Load the **chatbot-hosted URL** in the webview.

![Image](https://mintcdn.com/wotnot/Kf2EOxW9_nLCdHhp/images/image-636.png?fit=max\&auto=format\&n=Kf2EOxW9_nLCdHhp\&q=85\&s=318459a9087158f44373169a4061fd42)

The URL and embed options are generated from the bot's **Embed** configuration.

For additional web embed parameters, see the [Web](https://app.mintlify.com/wotnot/wotnot/~/2430cbd5-5d6d-4ab5-9293-a45bfab38917) deployment documentation.

### Implementation notes

A webview is simple to implement, but a few mobile-specific behaviours need to be handled by your application.

On your mobile app, add a help icon or option on your menu that allows users to open this page.

Doing this will open the chatbot-hosted page that you created in Step 1.

![Image 1](https://mintcdn.com/wotnot/GOCffUmuL5X3C7oo/images/image-1.webp?fit=max\&auto=format\&n=GOCffUmuL5X3C7oo\&q=85\&s=a9d89879214b9a0e17e27d124f1d5271)

JavaScript must be enabled in the webview for the chatbot to work correctly.

```javascript theme={null}
// Example code to open chatbot-hosted URL as webview 

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("https://chatbot-hosted-webpage-url");
```

### Passing user context

If your mobile application already knows information about the logged-in user, pass that information to the chatbot instead of asking the user to provide it again.

Use the same user context or session data supported by the WotNot web deployment.

For example, you may pass information such as:

```json theme={null}
{ 
    "name": "John Doe", 
    "email": "john@example.com", 
    "phone": "+919999999999" 
}
```

> [!WARNING]
>
> Use only the user information your agent needs. Do not expose sensitive application data to the chatbot unnecessarily.

# **Android SDK**

This guide explains how to install and configure WotNot’s Android SDK to embed the native chat widget inside your Android app.

### Installing

**1. Add dependency**

Add the WotNot SDK and required Android libraries in your app-level `build.gradle` file:

```java theme={null}
dependencies {
    // WotNot Chatbot SDK
    implementation 'io.wotnot.android:chatbotsdk:1.0.3'

    // Required Android dependencies
    implementation 'androidx.core:core-ktx:1.13.1'
    implementation 'androidx.appcompat:appcompat:1.7.0'
    implementation 'com.google.android.material:material:1.12.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.7'
    implementation 'androidx.fragment:fragment-ktx:1.8.5'
    implementation 'androidx.activity:activity-ktx:1.9.3'
}
```

**2. Sync Gradle**

In Android Studio:

* File → Sync Project with Gradle Files
* Or use the toolbar sync button

**3. Add required permissions**

Add the following permissions to your `AndroidManifest.xml`:

```javascript theme={null}
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```

### SDK Configuration

**Create a WidgetConfig**

The SDK requires a `WidgetConfig` object to initialize the chat widget.

```rust theme={null}
import com.widget.sdk.data.model.WidgetConfig
import com.widget.sdk.utils.VisitorKeyManager

// Initialize VisitorKeyManager first (optional, but recommended)
VisitorKeyManager.initialize(context)

val config = WidgetConfig(
    botId = "YOUR_BOT_ID",                    // Required: Your bot ID
    visitorKey = “VISITOR_KEY”, // Required: Visitor key (auto-generated if not set)
    accountKey = "YOUR_ACCOUNT_KEY",          // Required: Your account key
    accountId = YOUR_ACCOUNT_ID,              // Required: Your account ID (Int)
    
    // Optional Configurations
    isMessageAvatarVisible = true,            // Show/hide message avatars (default: true)
    isHeaderVisible = true,                   // Show/hide headers (default: true)
    conversationKey = null,                   // Optional: Pre-existing conversation key
    dataSessionPayload = null,                // Optional: Additional data payload
    badRequestMessage = "Bad request. Please check your configuration.",
    botNotActiveMessage = "Bot is not active."
)
```

### Where to find these credentials

**YOUR\_BOT\_ID** — open the bot you want to embed, and copy the bot\_id from the URL.

![Image](https://mintcdn.com/wotnot/Kf2EOxW9_nLCdHhp/images/image-640.png?fit=max\&auto=format\&n=Kf2EOxW9_nLCdHhp\&q=85\&s=f099a93fa84cd038c892a2e4919af57a)

**YOUR\_ACCOUNT\_ID** — goto Settings > Account Settings and copy the account\_id from the URL.

![Image](https://mintcdn.com/wotnot/Kf2EOxW9_nLCdHhp/images/image-641.png?fit=max\&auto=format\&n=Kf2EOxW9_nLCdHhp\&q=85\&s=268fd3915f5a3d7b26b2399462c251f9)

**YOUR\_ACCOUNT\_KEY** — Goto the bot list screen, open the embed option from context menu and copy the highlighted key.

![Image](https://mintcdn.com/wotnot/Kf2EOxW9_nLCdHhp/images/image-642.png?fit=max\&auto=format\&n=Kf2EOxW9_nLCdHhp\&q=85\&s=dd5c729bc724181940e904931502a234)

**Visitor key notes:**

* If you don’t provide a visitorKey, the SDK auto-generates and persists one.
* It’s recommended to provide the unique visitor key, as it helps uniquely identify each visitor and maintain their chats and session history.

### Initialize the SDK

Call `wn.initialize()` in your Application class or MainActivity.

```json theme={null}
import com.widget.sdk.wn

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        try {
            val config = WidgetConfig(
                botId = "YOUR_BOT_ID", //String
                visitorKey = "VISITOR_KEY_32_BIT_LONG", //String
                accountKey = "YOUR_ACCOUNT_KEY", //String
                accountId = "YOUR_ACCOUNT_ID" //Number
            )

            wn.initialize(this, config)

        } catch (e: Exception) {
            Log.e("SDK", "Initialization failed: ${e.message}")
        }
    }
}
```

> [card] IMPORTANT NOTE
>
> * Always initialize the SDK before launching any chat screen.
> * All required fields (botId, visitorKey, accountKey, accountId) must be present.
> * The SDK validates config and throws an exception on failure.

### Launching the chat screen

The SDK provides built-in functions to launch chat screens.

All functions optionally support `useAnimation = true`

**Conversation list screen:**

```javascript theme={null}
// Without animation
wn.launchConversationList(this)

// With animation (bottom-to-top slide)
wn.launchConversationList(this, useAnimation = true)
```

**Conversation detail screen without key:**

```javascript theme={null}
// Launch without animation
wn.launchConversationDetailScreenWithoutKey(this)

// Launch with animation
wn.launchConversationDetailScreenWithoutKey(this, useAnimation = true)
```

**Ending the conversation:**

```javascript theme={null}
// Ends the conversation, so a new conversation can be started
wn.endChat()
```

### Theme customization

You can fully customize the look of the chat widget using `WidgetTheme`.

**Theme options:**

| Property | Setter | Default | Used For |
| - | - | - | - |
| accentPrimary | setAccentPrimary() | #0075FF | Buttons, headers, and links |
| userMessageTextColor | setUserMessageTextColor() | #FFFFFF | User message text and timestamp |
| accentSecondary | setAccentSecondary() | #D4E3FF | Secondary accents |
| gray8 | setGray8() | #F2F5F8 | Bot message background |
| botMessageTextColor | setBotMessageTextColor() | #1C1C1E | Bot text and timestamp |
| failurePrimary | setFailurePrimary() | #FF0000 | Error messages |
| failureSecondary | setFailureSecondary() | #FFEBEE | Error states |

**Applying a theme:**

```javascript theme={null}
// After SDK initialization
val customTheme = WidgetTheme.Builder()
    .setAccentPrimary(Color.parseColor("#0075ff"))
    .setBackgroundColor(Color.WHITE)
    .build()

wn.setTheme(customTheme)
```

### Passing user data

### Opening and closing the chat

```rust wrap theme={null}
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.widget.sdk.wn
import com.widget.sdk.data.model.WidgetConfig
import com.widget.sdk.theme.WidgetTheme
import com.widget.sdk.utils.VisitorKeyManager
import android.graphics.Color
import android.util.Log

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Step 1: Initialize VisitorKeyManager
        VisitorKeyManager.initialize(this)

        // Step 2: Build WidgetConfig
        val config = WidgetConfig(
            botId = "YOUR_BOT_ID",
            visitorKey = VisitorKeyManager.getVisitorKey(),
            accountKey = "YOUR_ACCOUNT_KEY",
            accountId = YOUR_ACCOUNT_ID,
            isMessageAvatarVisible = true,
            isHeaderVisible = true
        )

        // Step 3: Initialize SDK
        try {
            wn.initialize(this, config)
        } catch (e: Exception) {
            Log.e("SDK", "Initialization failed: ${e.message}")
            return
        }

        // Step 4: Apply Theme
        val customTheme = WidgetTheme.Builder()
            .setAccentPrimary(Color.parseColor("#0075ff"))
            .setBackgroundColor(Color.WHITE)
            .setTextPrimaryColor(Color.parseColor("#1C1C1E"))
            .build()

        wn.setTheme(customTheme)

        // Step 5: Setup Launch Buttons
        findViewById<Button>(R.id.btnNewChat).setOnClickListener {
            wn.launchNewConversation(this, useAnimation = true)
        }

        findViewById<Button>(R.id.btnConversationList).setOnClickListener {
            wn.launchConversationList(this, useAnimation = true)
        }
    }
}
```

# **iOS SDK**

This guide walks you through installing, configuring, and launching the WotNot chat widget natively in your iOS app (SwiftUI or UIKit).

### Installing

#### **Step 1: Add the SDK via Swift Package Manager (Recommended)**

Supports Xcode 13+ for both SwiftUI and UIKit projects.

**1. Open Xcode → Add SPM Package**

File → Add Packages…

**2. Enter the SDK Package URL**

In the dialog box that appears, paste the WotNotSDK repository URL into the search bar/text field.

[https://github.com/wotnotbot/ios-sdk](https://github.com/wotnotbot/ios-sdk)

**3. Configure dependency rule**

* Rule: *Up to Next Major Version*
* Set the version to the required SDK version

> [!NOTE]
>
> This ensures you automatically get minor improvements without risking breaking changes.

**4. Add the package**

Click Add Package, and Xcode will fetch and integrate the SDK.

#### Step 2: **Add required permissions**

Add the following permission to your `Info.plist`:

```javascript theme={null}
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
```

#### Step 3: **Import the SDK**

Add this import wherever you use the widget:

```swift theme={null}
import SwiftUI
import WotNotSDK
```

### Configuration

#### Step 1: Create a WidgetConfig

This `WidgetConfig` object contains your bot credentials and optional UI settings.

```swift theme={null}
import WotNotSDK

let config = WidgetConfig(
    botId: "YOUR_BOT_ID",                    // Required: Your bot ID
    visitorKey: "VISITOR_KEY",                // Required: Visitor key (32-bit long string)
    accountKey: "YOUR_ACCOUNT_KEY",           // Required: Your account key
    accountId: YOUR_ACCOUNT_ID,               // Required: Your account ID (Int)
    
    // Optional Configuration
    conversationKey: nil,                     // Optional: Pre-existing conversation key
    isMessageAvatarVisible: true,             // Show/hide message avatars (default: true)
    isHeaderVisible: true,                   // Show/hide headers (default: true)
    dataSessionPayload: nil,                 // Optional: Additional data payload
    badRequestMessage: "Bad request. Please check your configuration.",
    botNotActiveMessage: "Bot is not active."
)
```

**Where to find these credentials:**

**YOUR\_BOT\_ID** — open the bot you want to embed, and copy the bot\_id from the URL.

![Image](https://mintcdn.com/wotnot/Kf2EOxW9_nLCdHhp/images/image-637.png?fit=max\&auto=format\&n=Kf2EOxW9_nLCdHhp\&q=85\&s=5c1def3b063b6d9b96372ec1373714e6)

**YOUR\_ACCOUNT\_ID** — go to Settings → Account Settings and copy the account\_id from the URL.

![Image](https://mintcdn.com/wotnot/Kf2EOxW9_nLCdHhp/images/image-638.png?fit=max\&auto=format\&n=Kf2EOxW9_nLCdHhp\&q=85\&s=095e27e47814c44efb9dc9f69ae692d3)

**YOUR\_ACCOUNT\_KEY** — Goto the bot list screen, open the embed option from context menu and copy the highlighted key.

![Image](https://mintcdn.com/wotnot/Kf2EOxW9_nLCdHhp/images/image-639.png?fit=max\&auto=format\&n=Kf2EOxW9_nLCdHhp\&q=85\&s=0983e8f2dfe57ec1d8f8d20779716b00)

#### Step 2: Initialize the SDK

Initialize inside your `App` struct or `View`

```swift theme={null}
import SwiftUI
import WotNotSDK

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    initializeSDK()
                }
        }
    }
    
    private func initializeSDK() {
        Task {
            do {
                let config = WidgetConfig(
                    botId: "YOUR_BOT_ID",
                    visitorKey: "VISITOR_KEY_32_BIT_LONG",
                    accountKey: "YOUR_ACCOUNT_KEY",
                    accountId: "YOUR_ACCOUNT_ID"
                )
                
                try await wn.initialize(config: config)

            } catch {
                print("SDK Initialization failed: \(error.localizedDescription)")
            }
        }
    }
}
```

> [card] IMPORTANT NOTE
>
> * SDK must be initialized before launching any chat UI.
> * Initialization is asynchronous (async throws), so use Task or an async context.
> * All required fields (i.e. `botID`, `visitorKey`, `accountKey`, `accountID`) must be provided.
> * The SDK performs validation and throws errors if credentials are invalid.

### Launching chat screens (SwiftUI)

The SDK provides several functions that return SwiftUI `View` objects. These can be presented using `NavigationLink`, `.sheet()`, or other SwiftUI presentation methods.

**Launch conversation list (Full Screen):**

Opens the conversation in a full screen mode.

```swift theme={null}
do {
    let view = try wn.launchConversationListFullScreen()
    // Present the view
} catch {
    print("Failed to launch: \(error)")
}
```

**Launch conversation list (Bottom Sheet):**

Opens the conversation list in a bottom sheet.

```swift theme={null}
do {
    let view = try wn.launchConversationListBottomSheet()
    // Present bottom sheet
} catch {
    print("Failed to launch: \(error)")
}
```

### Theme customization

Customize colors for bubbles, text, accents, and error states.

**Theme colors reference:**

| Property | Setter | Default | Used For |
| - | - | - | - |
| accentPrimary | accentPrimary: Color(...) | #0075FF | Buttons, headers, and links |
| userMessageTextColor | visitorMessageTextColor: Color(...) | #FFFFFF | User message text and timestamp |
| botMessageBackgroundColor | botMessageBackgroundColor: Color(...) | #F2F5F8 | Bot message bubble background |
| botMessageTextColor | botMessageTextColor: Color(...) | #1C1C1E | Bot text and timestamp |
| accentSecondary | accentSecondary: Color(...) | #D4E3FF | Secondary accents |
| gray8 | setGray8() | #F2F5F8 | Bot message background |
| failurePrimary | failurePrimary: Color(...) | #FF0000 | Error messages |
| failureSecondary | failureSecondary: Color(...) | #FFEBEE | Error states |

**Applying a custom theme:**

Apply the theme after initialization:

```swift theme={null}
Task {
    do {
        // 1. Initialize SDK (omitted for brevity)
        // try await wn.initialize(config: config)
        
        // 2. Apply custom theme
        let customTheme = WidgetTheme(
            // Right side (user)
            accentPrimary: Color(red: 0/255, green: 117/255, blue: 255/255), // #0075ff
            visitorMessageTextColor: Color.white,
            
            // Left side (bot)
            botMessageBackgroundColor: Color(red: 242/255, green: 245/255, blue: 248/255), // #F2F5F8
            botMessageTextColor: Color(red: 28/255, green: 28/255, blue: 30/255), // #1C1C1E
            
            // Accent colors
            accentSecondary: Color(red: 212/255, green: 227/255, blue: 255/255), // #d4e3ff
            
            // Failure colors
            failurePrimary: Color.red
        )
        
        try wn.setTheme(customTheme)
    } catch {
        print("SDK initialization or theme setup failed: \(error)")
    }
}
```

### Passing user data

### Opening and closing the chat

```swift theme={null}
import SwiftUI
import WotNotSDK

@main
struct WotNotDemoApp: App {
    
    init() {
        Task { await initializeSDK() }
    }
    
    var body: some Scene {
        WindowGroup {
            // Embed ContentView in a NavigationView for proper UI context
            NavigationView {
                ContentView()
            }
        }
    }
    
    // Asynchronous SDK Initialization Function
    private func initializeSDK() async {
        do {
            let config = WidgetConfig(
                botId: "YOUR_BOT_ID",
                visitorKey: "YOUR_VISITOR_KEY",
                accountKey: "YOUR_ACCOUNT_KEY",
                accountId: "YOUR_ACCOUNT_ID"
            )
            
            // Set a basic theme (optional, for visual consistency)
            let theme = WidgetTheme(
                primaryBlue: Color.blue,
                primaryRed: Color.red
            )
            
            try wn.setTheme(theme)
            try await wn.initialize(config: config)

        } catch {
            print("SDK Initialization Error: \(error.localizedDescription)")
            // The ContentView status rows will reflect the failed state
        }
    }
}


// --- 2. ContentView: Launches Bottom Sheet Directly ---
struct ContentView: View {
    @State private var showingAlert = false
    @State private var alertMessage = ""
    
    var body: some View {
        VStack(spacing: 30) {
            
            // Header
            VStack(spacing: 16) {
                Image(systemName: "message.circle.fill")
                    .font(.system(size: 80))
                    // Use theme color for header icon
                    .foregroundColor(wn.getTheme()?.primaryBlue ?? Color.blue) 
                
                Text("WotNot SDK")
                    .font(.largeTitle)
                    .fontWeight(.bold)
                
                Text("Chat Integration")
                    .font(.subheadline)
                    // Use theme color for secondary text
                    .foregroundColor(wn.getTheme()?.textSecondaryColor ?? Color.secondary)
            }
            
            // SDK Status
            VStack(spacing: 12) {
                StatusRow(
                    title: "SDK Status",
                    status: wn.initializationStatus.description,
                    isSuccess: wn.isSDKInitialized()
                )
                
                StatusRow(
                    title: "Validation Status",
                    status: wn.validationStatus.description,
                    isSuccess: wn.isBotValidated()
                )
            }
            
            // Open Bottom Sheet Button - Simple SDK method call!
            Button(action: {
                openBottomSheetConversationList()
            }) {
                HStack {
                    Image(systemName: "list.bullet.rectangle")
                        .font(.title3)
                    
                    Text("Open Conversation List")
                        .fontWeight(.semibold)
                }
                // Use theme color for foreground and background
                .foregroundColor(wn.getTheme()?.white ?? Color.white)
                .frame(maxWidth: .infinity)
                .padding()
                .background(wn.getTheme()?.primaryBlue ?? Color.blue)
                .cornerRadius(12)
            }
            // Button is disabled until the SDK confirms initialization
            .disabled(!wn.isSDKInitialized()) 
            
            Spacer()
        }
        .padding()
        .navigationTitle("SDK Home")
        .alert("Alert", isPresented: $showingAlert) {
            Button("OK") { }
        } message: {
            Text(alertMessage)
        }
    }
    
    // Function to launch the SDK UI
    private func openBottomSheetConversationList() {
        do {
            // Directly calls the SDK's presentation function
            try wn.presentBottomSheetConversationList()
        } catch {
            alertMessage = "Failed to open conversation list: \(error.localizedDescription)"
            showingAlert = true
        }
    }
}



// --- 3. Helper Structs and Extensions ---

// Status Row Component
struct StatusRow: View {
    let title: String
    let status: String
    let isSuccess: Bool
    
    var body: some View {
        HStack {
            Text(title)
                .fontWeight(.medium)
            Spacer()
            Text(status)
                .foregroundColor(wn.getTheme()?.textSecondaryColor ?? Color.secondary)
            Image(systemName: isSuccess ? "checkmark.circle.fill" : "xmark.circle.fill")
                .foregroundColor(isSuccess ? (wn.getTheme()?.primaryGreen ?? Color.green) : (wn.getTheme()?.primaryRed ?? Color.red))
        }
        .padding()
        .background(wn.getTheme()?.lightGray ?? Color(.systemGray6))
        .cornerRadius(12)
    }
}

// Extension for InitializationStatus
extension InitializationStatus {
    var description: String {
        switch self {
        case .notInitialized:
            return "Not Initialized"
        case .initialized:
            return "Initialized"
        case .initializationFailed(let error):
            return "Failed: \(error)"
        @unknown default:
            return "Unknown"
        }
    }
}

// Extension for ValidationStatus
extension ValidationStatus {
    var description: String {
        switch self {
        case .notValidated:
            return "Not Validated"
        case .validating:
            return "Validating..."
        case .validated:
            return "Validated"
        case .validationFailed(let error):
            return "Failed: \(error)"
        @unknown default:
            return "Unknown"
        }
    }
}
```

# Testing

Test the mobile integration in both an emulator/simulator and on a physical device.

* Build and run your application using an **Android emulator** or **iOS simulator**.
* Open the screen containing the WotNot agent.
* Send several messages and verify that responses are displayed correctly.
* Close and reopen the chat and verify that conversation history behaves as expected.
* Test the same flow on a physical **Android or iOS device**.

Some behaviours require testing on a real device because they depend on the operating system or device hardware.

Test at minimum:

* Push notifications, if enabled
* Mobile keyboard behaviour
* File selection and uploads
* Back navigation
* External links
* Screen orientation
* Network changes between Wi-Fi and mobile data
* Conversation persistence

> [!TIP]
>
> An integration that works in an emulator or simulator can still behave differently on a physical device. Always complete a device test before releasing the integration to users.

# Troubleshooting

> [accordion] Widget not loading in the webview
>
> Check that:
>
> * JavaScript is enabled.
> * The chatbot URL is correct.
> * The webview has network access.
> * The bot is active and published.
> * Your application is not blocking the chatbot URL.
>
> For Android, verify that JavaScript is enabled before calling `loadUrl()`.
>
> ```kotlin theme={null}
> webView.settings.javaScriptEnabled = true
> webView.loadUrl("https://chatbot-hosted-webpage-url")
> ```

> [accordion] SDK build failure or dependency conflict
>
> Check that:
>
> * You are using a supported version of Android Studio or Xcode.
> * The WotNot SDK version is compatible with your project.
> * Required dependencies are available.
> * Gradle or Swift Package Manager has completed dependency resolution.
> * There are no conflicting versions of the same Android or iOS libraries.
>
> If the problem started after upgrading the SDK, verify the SDK's release requirements before changing unrelated project dependencies.

> [accordion] User data not reaching variables
>
> Verify that:
>
> * The visitor key is set correctly.
> * The same visitor key is used for the intended user.
> * The user or session payload contains the expected values.
> * WotNot variables are mapped to the correct data fields.
> * The SDK is initialized before the chat is opened.
>
> Use a test user with known values to verify the complete flow.

> [accordion] Keyboard covering the input field
>
> This is usually caused by the application or webview not resizing correctly when the mobile keyboard opens.
>
> Check the keyboard and input configuration for the target platform and test on multiple screen sizes.
>
> For webview integrations, also test both portrait and landscape orientations.

> [accordion] Links opening inside the webview instead of the browser
>
> Intercept links that should be opened externally and pass them to the platform's browser instead of allowing the webview to navigate to them.
>
> This is particularly important for payment pages, external websites, app store links, and other destinations that should not remain inside the chatbot.

> [accordion] File upload not working on one platform
>
> Verify that the platform's webview or native SDK has the required file access configuration.
>
> Test the file picker on a physical device and check whether the selected file type is supported.
>
> If uploads work on one platform but not another, compare the Android and iOS webview or file-picker implementation rather than changing the WotNot bot configuration first.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.