# Digia WebEngage Integration

***

The Digia WebEngage plugin intercepts **WebEngage in-app** campaign payloads and pipes them directly into Digia's rendering engine. When a campaign triggers, the plugin maps the incoming payload to your custom UI designs built in Digia Studio, instantly rendering a 100% native experience on the device—no WebViews required.

This guide walks you through the end-to-end integration process—covering SDK installation, plugin initialization, and how to map your dashboard campaigns to Digia's native components.

## 1. Prerequisites

Before integrating, ensure you have:

* **Digia Access Key**: Log in to [Digia Studio](https://app.digia.tech), open your project, and copy your key from **Settings → App Settings**.
* **Active WebEngage Account**: Ensure you have an active WebEngage workspace with access to your License Code.
* **WebEngage SDK**: Installed and initialized (see [Flutter](https://docs.webengage.com/docs/flutter-getting-started), [Android](https://docs.webengage.com/docs/android-integration-guide), [iOS](https://docs.webengage.com/docs/ios-integration-guide), or [React Native](https://docs.webengage.com/docs/react-native-getting-started) Quick Start).

### Minimum Supported Versions

| Platform         | Environment                                                       | Minimum Dependencies                                                                                                                               |
| ---------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Flutter**      | <p>Dart <code>>=3.3.0</code><br>Flutter <code>>=3.20.0</code></p> | <p><code>digia\_engage: ^1.1.2</code><br><code>digia\_webengage\_plugin: ^1.0.0</code><br><code>webengage\_flutter: installed</code></p>           |
| **Android**      | `minSdk 24`                                                       | <p><code>tech.digia:engage:1.0.0</code><br><code>tech.digia:engage-webengage:1.0.0</code><br><code>com.webengage:android-sdk: installed</code></p> |
| **iOS (Swift)**  | iOS `16+`                                                         | <p><code>DigiaEngage: 1.0.0</code><br><code>DigiaWebEngage: 1.0.0</code></p>                                                                       |
| **React Native** | React Native `0.73+`                                              | <p><code>@digia-engage/core: ^1.0.0</code><br><code>@digia-engage/webengage: ^1.0.0</code><br><code>webengage-react-native: installed</code></p>   |

***

## 2. Install

> **Note:** We assume the core WebEngage SDK is already installed and initialized as part of your standard app setup (see [Prerequisites](#1-prerequisites)). The snippets below only cover adding the Digia plugin packages.

{% tabs %}
{% tab title="Flutter" %}
Add the Digia packages using the `flutter pub add` command:

```bash
flutter pub add digia_engage digia_webengage_plugin
```

{% endtab %}

{% tab title="Android" %}
Add dependencies in app `build.gradle.kts`:

```kotlin
dependencies {
  implementation("tech.digia:engage:1.0.0")
  implementation("tech.digia:engage-webengage:1.0.0")
}
```

Sync the project (Gradle sync).
{% endtab %}

{% tab title="iOS (Swift)" %}
Add packages using **Xcode → File → Add Package Dependencies** (or in `Package.swift`):

```swift
dependencies: [
    .package(url: "https://github.com/Digia-Technology-Private-Limited/digia_engage_iOS.git", exact: "1.0.0"),
    .package(url: "https://github.com/Digia-Technology-Private-Limited/digia_webengage_iOS.git", exact: "1.0.0"),
],
```

Then add these products to your app target dependencies:

* `DigiaEngage`
* `DigiaWebEngage`
  {% endtab %}

{% tab title="React Native" %}
Install the Digia packages using npm or yarn:

```bash
npm install @digia-engage/core@1.0.0 @digia-engage/webengage@1.0.0
```

**iOS — Additional Native Setup (CocoaPods)**

Add the Digia iOS pod to your `Podfile`:

```ruby
pod 'DigiaEngage',
  :git => 'https://github.com/Digia-Technology-Private-Limited/digia_engage_iOS.git',
  :tag => '1.0.0'
```

Then run:

```bash
cd ios && pod install
```

{% endtab %}
{% endtabs %}

***

## 3. Initialize Digia with WebEngage

Initialize Digia **after** the WebEngage SDK and **before** plugin registration.

{% tabs %}
{% tab title="Flutter" %}
In your `main.dart`, initialize Digia and register the WebEngage plugin:

```dart
import 'package:digia_webengage_plugin/digia_webengage_plugin.dart';
import 'package:digia_engage/digia_engage.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 1. Initialize Digia before registering any CEP plugin.
  await Digia.initialize(
    DigiaConfig(apiKey: 'YOUR_ACCESS_KEY'),
  );

  // 2. Register the Digia WebEngage plugin.
  Digia.register(DigiaWebEngagePlugin());

  runApp(const MyApp());
}
```

**iOS — Additional Setup (`AppDelegate.swift`)**

On Flutter iOS, add the following to your `AppDelegate.swift` to wire the WebEngage push notification delegate through the Digia bridge:

```swift
import Flutter
import UIKit
import WebEngage
import webengage_flutter
import digia_engage_webengage
import UserNotifications

@main
@objc class AppDelegate: FlutterAppDelegate {

  var bridge: WebEngagePlugin? = nil

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    UNUserNotificationCenter.current().delegate = self
    application.registerForRemoteNotifications()

    // Create the Flutter-WebEngage bridge.
    bridge = WebEngagePlugin()

    // Wire push notification delegates.
    WebEngage.sharedInstance().pushNotificationDelegate = self.bridge
    WebEngage.sharedInstance().application(
      application,
      didFinishLaunchingWithOptions: launchOptions,
      notificationDelegate: DigiaSuppressPlugin.shared
    )
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
```

{% endtab %}

{% tab title="Android" %}
In your `Application` class, configure WebEngage and then initialize Digia:

```kotlin
import android.app.Application
import com.digia.engage.Digia
import com.digia.engage.DigiaConfig
import com.digia.engage.DigiaLogLevel
import com.webengage.sdk.android.WebEngageConfig
import com.webengage.sdk.android.WebEngageActivityLifeCycleCallbacks
import com.webengage.sdk.android.WebEngagePlugin

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        // 1. Initialize the WebEngage SDK.
        val webEngageConfig = WebEngageConfig.Builder()
            .setWebEngageKey("YOUR_WEB_ENGAGE_KEY")
            .setDebugMode(true)
            .build()
        registerActivityLifecycleCallbacks(
            WebEngageActivityLifeCycleCallbacks(this, webEngageConfig)
        )

        // 2. Initialize Digia before registering any CEP plugin.
        Digia.initialize(
            this,
            DigiaConfig(
                apiKey = "YOUR_ACCESS_KEY",
                logLevel = DigiaLogLevel.VERBOSE
            )
        )

        // 3. Register the Digia WebEngage plugin.
        Digia.register(WebEngagePlugin())
    }
}
```

{% endtab %}

{% tab title="iOS (Swift)" %}
Register `AppDelegate` via `@UIApplicationDelegateAdaptor` so the WebEngage SDK is initialized before any scene is created.

**`AppDelegate.swift`**

```swift
import UIKit
@preconcurrency import WebEngage
import DigiaEngageWebEngage

@objc final class AppDelegate: NSObject, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        WebEngage.sharedInstance().application(
            application,
            didFinishLaunchingWithOptions: launchOptions,
            notificationDelegate: DigiaWebEngagePlugin.notificationDelegate
        )
        return true
    }
}
```

**App entry point (SwiftUI)**

```swift
import SwiftUI
import DigiaEngage
import DigiaEngageWebEngage

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    init() {
        Task {
            do {
                try? await Digia.initialize(
                    DigiaConfig(
                        apiKey: "YOUR_ACCESS_KEY",
                        logLevel: .verbose
                    )
                )
                Digia.register(DigiaWebEngagePlugin())
            }
        }
    }

    var body: some Scene {
        WindowGroup {
            RootView()
        }
    }
}
```

{% endtab %}

{% tab title="React Native" %}
In your root component (e.g. `App.tsx`), initialize Digia and register the WebEngage plugin:

```tsx
import { useEffect } from 'react';
import { Digia } from '@digia-engage/core';
import { DigiaWebEngagePlugin } from '@digia-engage/webengage';

export function RootApp() {
  useEffect(() => {
    (async () => {
      // 1. Initialize Digia before registering any CEP plugin.
      await Digia.initialize({ apiKey: 'YOUR_ACCESS_KEY' });

      // 2. Register the Digia WebEngage plugin.
      //    The overlay host attaches automatically — no <DigiaHostView> needed.
      Digia.register(
        new DigiaWebEngagePlugin(),
      );
    })().catch(console.error);
  }, []);

  return <AppNavigator />;
}
```

**iOS — Additional Native Setup (`AppDelegate.swift`)**

On React Native iOS, add the following to your `AppDelegate.swift` to wire the WebEngage in-app notification delegate through the Digia bridge:

```swift
import WebEngage
import DigiaWebEngage

// Inside application(_:didFinishLaunchingWithOptions:):
WebEngage.sharedInstance().application(
    application,
    didFinishLaunchingWithOptions: launchOptions,
    notificationDelegate: WEDigiaSuppressProxy.shared()
)
```

{% endtab %}
{% endtabs %}

***

## 4. How Digia Maps to WebEngage Campaigns

| Experience Type | Digia Component | WebEngage Campaign Type | Description                                                                                               |
| --------------- | --------------- | ----------------------- | --------------------------------------------------------------------------------------------------------- |
| **Nudge**       | `DigiaHost`     | In-App Notification     | Receives the campaign payload and renders overlay experiences (bottom sheets, dialogs) above app content. |
| **Inline**      | `DigiaSlot`     | In-App Notification     | Receives placement key/value pairs and renders inline content (banners, cards) within the app layout.     |

{% @mermaid/diagram content="flowchart TD
Trigger\[WebEngage Campaign Trigger]
SDK\[WebEngage SDK]
Plugin\[Digia WebEngage Plugin]
Runtime\[digia\_engage runtime]
UI\[Campaign UI<br>native widgets from Digia Studio]

```
Trigger --> SDK
SDK -- "In-app notification callback" --> Plugin
Plugin -- "maps payload -> InAppPayload" --> Runtime
Runtime -- "SHOW_BOTTOM_SHEET / SHOW_DIALOG<br>-> DigiaHost renders overlay" --> UI
Runtime -- "SHOW_INLINE<br>-> DigiaSlot renders inline" --> UI" %}
```

***

## 5. Setting Up Nudges

### In-App Campaigns: What They Are and Why They're Needed

WebEngage delivers in-app notification payloads to your app code when a campaign triggers. The Digia WebEngage plugin registers an in-app notification listener that intercepts this payload, parses the `<digia>` custom HTML tag, maps it to a `SHOW_BOTTOM_SHEET` or `SHOW_DIALOG` command, and delegates rendering to Digia's runtime. **Without configuring the WebEngage campaign as Custom HTML with a `<digia>` tag, the experience will not render.**

### In-App Campaigns: Set Up in Dashboard

No device-side sync is required — the plugin responds automatically once registered. Configure your campaign in the WebEngage dashboard:

1. Log in to the **WebEngage dashboard** and go to **Campaigns → In-App Notifications**.
2. Click **Create** and give the campaign a name.
3. In the **Content** step, choose **Custom HTML** as the template type.
4. Configure the trigger event, audience, and schedule as required.
5. In the **Custom HTML** editor, enter the Digia `<digia>` tag (see [Trigger a Nudge from WebEngage](#trigger-a-nudge-from-webengage) below).

### Add the Nudge Container

Wrap your app root so overlay campaigns can render above app content.

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

```dart
import 'package:digia_engage/digia_engage.dart';
import 'package:flutter/material.dart';

MaterialApp(
  navigatorKey: DigiaHost.navigatorKey,
  navigatorObservers: [DigiaNavigatorObserver()],
  builder: (context, child) => DigiaHost(
    child: child!,
  ),
  home: const HomeScreen(),
)
```

{% endtab %}

{% tab title="Android (Jetpack Compose)" %}

```kotlin
import com.digia.engage.DigiaHost

DigiaHost {
    AppNavHost()
}
```

{% endtab %}

{% tab title="Android (XML Layout)" %}
For XML-based Android layouts, use `DigiaHostView` as a full-screen overlay in your root layout. This is the View-system wrapper around `DigiaHost`, so you do not need Compose code in your `Activity` or `Fragment`.

```xml
<FrameLayout
    android:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Your normal views / fragments -->

    <!-- Must be the last child so it draws on top -->
    <com.digia.engage.DigiaHostView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>
```

Or programmatically in your Activity:

```kotlin
import com.digia.engage.DigiaHostView

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

    val rootLayout = findViewById<FrameLayout>(R.id.root_layout)
    val digiaHost = DigiaHostView(this)
    rootLayout.addView(
        digiaHost,
        FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT,
        )
    )
}
```

{% endtab %}

{% tab title="iOS (Swift)" %}

```swift
import SwiftUI
import DigiaEngage

struct RootContainerView: View {
    var body: some View {
        DigiaHost {
            AppRootView()
        }
    }
}
```

{% endtab %}

{% tab title="React Native" %}
No additional host container is required. The Digia overlay host attaches automatically to the Activity when `Digia.register(new DigiaWebEngagePlugin())` is called during initialization — no `<DigiaHostView>` needed in your component tree.
{% endtab %}
{% endtabs %}

### Trigger a Nudge from WebEngage

In the WebEngage campaign **Custom HTML** editor, enter a `<digia>` tag with the appropriate attributes:

```html
<digia
  command="SHOW_BOTTOM_SHEET"
  view-id="promo_offer_sheet"
  args='{
    "coupon": "SAVE20",
    "title": "Special Offer",
    "cta": { "text": "Claim Now" }
  }'
></digia>
```

| Attribute | Required | Example value           | Description                                                                                                |
| --------- | -------- | ----------------------- | ---------------------------------------------------------------------------------------------------------- |
| `command` | Yes      | `SHOW_BOTTOM_SHEET`     | `SHOW_BOTTOM_SHEET` or `SHOW_DIALOG`.                                                                      |
| `view-id` | Yes      | `promo_offer_sheet`     | Digia page slug. See [Finding Slugs](https://docs.digia.tech/studio-workspace/builder-tool/finding-slugs). |
| `args`    | No       | `'{"coupon":"SAVE20"}'` | JSON object passed as a single-quoted string. Available in Digia page logic at runtime.                    |

> **`args` format:** Write the value as a single-quoted JSON object directly in the HTML attribute — e.g., `args='{"coupon":"SAVE20"}'`. The plugin parses it automatically.

***

## 6. Setting Up Inline Widgets

`DigiaSlot` is a composable/widget that renders Digia-powered content inline within your screen layout. Each slot is identified by a `placementKey` — a string that must match the `placement` attribute in the WebEngage campaign `<digia>` tag. When an in-app campaign with `type="inline"` is active, Digia resolves the component to display for each placement key and renders it inside the slot. If no campaign is active for a slot, it collapses to zero height.

### Add an Inline Slot

Place `DigiaSlot` where you want in-app inline content rendered.

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

```dart
import 'package:digia_engage/digia_engage.dart';
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: ListView(
        children: const [
          // Renders a Digia-powered banner campaign at the top of the feed.
          // placementKey must match the placementId in the WebEngage campaign payload.
          DigiaSlot('home_hero_banner'),
          SizedBox(height: 16),
          ProductCarousel(),
          SizedBox(height: 16),
          // Renders an inline offer card between content sections.
          DigiaSlot('product_offers'),
          SizedBox(height: 16),
          RecommendationList(),
        ],
      ),
    );
  }
}
```

{% endtab %}

{% tab title="Android (Jetpack Compose)" %}

```kotlin
import com.digia.engage.DigiaSlot

// placementKey must match placementId in WebEngage campaign payload
Column {
    DigiaSlot(placementKey = "home_hero_banner")
    DigiaSlot(placementKey = "product_offers")
}
```

{% endtab %}

{% tab title="Android (XML Layout)" %}
For View/XML layouts, use `DigiaSlotView`. It wraps the Compose `DigiaSlot` API and reads `app:placementKey` from XML.

```xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <com.digia.engage.DigiaSlotView
        android:id="@+id/homeHeroBanner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:placementKey="home_hero_banner" />

    <com.digia.engage.DigiaSlotView
        android:id="@+id/productOffers"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:placementKey="product_offers" />

</LinearLayout>
```

Or set the placement programmatically after inflation:

```kotlin
import com.digia.engage.DigiaSlotView

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

    findViewById<DigiaSlotView>(R.id.homeHeroBanner).placementKey = "home_hero_banner"
    findViewById<DigiaSlotView>(R.id.productOffers).placementKey = "product_offers"
}
```

`DigiaSlotView` requires a `DigiaHostView` (or a Compose `DigiaHost`) in the same window so the Digia rendering engine is already mounted before the slot renders.
{% endtab %}

{% tab title="iOS (Swift)" %}

```swift
import SwiftUI
import DigiaEngage

struct HomeScreen: View {
    var body: some View {
        ScrollView {
            VStack(spacing: 16) {
                DigiaSlot("home_hero_banner")
                ProductCarousel()
                DigiaSlot("product_offers")
                RecommendationList()
            }
            .padding()
        }
    }
}
```

{% endtab %}

{% tab title="React Native" %}

```tsx
import React from 'react';
import { ScrollView } from 'react-native';
import { DigiaSlotView } from '@digia-engage/webengage';

export function HomeScreen() {
  return (
    <ScrollView>
      {/* placementKey must match the placement in the WebEngage campaign payload */}
      <DigiaSlotView placementKey='home_hero_banner' />

      <ProductCarousel />

      <DigiaSlotView placementKey='product_offers' />

      <RecommendationList />
    </ScrollView>
  );
}
```

{% endtab %}
{% endtabs %}

### Serve Inline Content from WebEngage

In the WebEngage campaign **Custom HTML** editor, enter a `<digia>` tag with `type="inline"` and the matching placement key:

```html
<digia
  type="inline"
  placement="home_hero_banner"
  view-id="home_hero_banner-v2N8"
  args='{
    "title": "Special Offer",
    "message": "Get 20% off",
    "cta": { "text": "Shop Now" }
  }'
></digia>
```

| Attribute   | Required | Description                                                                                                                             |
| ----------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `type`      | Yes      | Must be `inline` for inline slots.                                                                                                      |
| `placement` | Yes      | Must match the `DigiaSlot` / `DigiaSlotView` placement key in your app code (case-sensitive).                                           |
| `view-id`   | Yes      | Digia component or page slug. See [Finding Slugs](https://docs.digia.tech/studio-workspace/builder-tool/finding-slugs) for slug lookup. |
| `args`      | No       | JSON object passed as a single-quoted string. Available in Digia page logic at runtime.                                                 |

***

## 7. Test Your Integration

Follow these steps to verify end-to-end functionality before releasing:

1. **Verify initialization order** — `Digia.initialize` completes, then `Digia.register(DigiaWebEngagePlugin(...))` / `Digia.register(WebEngagePlugin())`, before `runApp` / first activity.
2. **Verify host placement** — `DigiaHost` must be in `MaterialApp.builder` (Flutter), the root Composable (Android Compose), or the root SwiftUI wrapper (iOS). For Android View/XML apps, `DigiaHostView` should be mounted once as the last full-screen child of the root `ViewGroup`. For React Native, the host overlay attaches automatically on `Digia.register(...)` — no manual host placement needed.
3. **Verify Flutter iOS AppDelegate** — confirm `DigiaSuppressPlugin.shared` is passed as the `notificationDelegate` in `AppDelegate.swift`.
4. **Create a test campaign** — create an in-app campaign with a known `viewId` and trigger it immediately for your test device.
5. **Verify inline slots** — place `DigiaSlot` / `DigiaSlotView` on a visible screen, create an in-app campaign with `SHOW_INLINE` and a matching `placementKey`, and confirm content renders.
6. **Verify screen tracking** — navigate between screens and confirm that screen-triggered campaigns fire on the correct screen (use `DigiaNavigatorObserver` on Flutter, `Digia.setCurrentScreen(...)` or `digiaScreen("...")` in Android View/XML apps, route/screen change hooks calling `Digia.setCurrentScreen(...)` on Swift, and navigation listeners calling `Digia.setCurrentScreen(...)` on React Native).

### Health Check

Use `plugin.healthCheck()` to verify plugin wiring. The report always includes `isHealthy` plus diagnostic metadata.

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

```dart
final plugin = DigiaWebEngagePlugin();
Digia.register(plugin);

// Later, for testing:
final report = plugin.healthCheck();
if (!report.isHealthy) {
  debugPrint('Plugin issue: ${report.issue}');
  debugPrint('Resolution: ${report.resolution}');
}
```

{% endtab %}

{% tab title="Android" %}

```kotlin
val plugin = WebEngagePlugin()
Digia.register(plugin)

// Later, for testing:
val report = plugin.healthCheck()
if (!report.isHealthy) {
  Log.w("Digia", "Plugin issue: ${report.issue} - ${report.resolution}")
}
```

{% endtab %}

{% tab title="iOS (Swift)" %}

```swift
let plugin = DigiaWebEngagePlugin()
Digia.register(plugin)

// Later, for testing:
let report = plugin.healthCheck()
if !report.isHealthy {
    print("Plugin issue: \(report.issue)")
    print("Resolution: \(report.resolution)")
}
```

{% endtab %}

{% tab title="React Native" %}

```tsx
import { Digia } from '@digia-engage/core';
import { DigiaWebEngagePlugin } from '@digia-engage/webengage';

const plugin = new DigiaWebEngagePlugin();
Digia.register(plugin);

// Later, for testing:
const report = plugin.healthCheck();
if (!report.isHealthy) {
  console.warn('Plugin health check failed', report.metadata);
}
```

{% endtab %}
{% endtabs %}

***

## 8. Troubleshooting

### Campaign not rendering

* Confirm initialization order — `Digia.initialize(...)` then `Digia.register(DigiaWebEngagePlugin(...))` / `Digia.register(WebEngagePlugin())`.
* Ensure the WebEngage campaign uses **Custom HTML** as the template type and the `<digia>` tag is correctly placed in the HTML editor.
* **Flutter iOS**: Confirm `DigiaSuppressPlugin.shared` is passed as the `notificationDelegate` in `AppDelegate.swift` and `import digia_engage_webengage` is present.
* Ensure `DigiaHost` is mounted in `MaterialApp.builder` (Flutter), the root Composable (Android Compose), or `DigiaHostView` is mounted as the last full-screen child in your Android View/XML root layout.
* Check `viewId` exactly matches the published Digia page slug (case-sensitive). See [Finding Slugs](https://docs.digia.tech/studio-workspace/builder-tool/finding-slugs).
* Verify campaign eligibility and trigger conditions in the WebEngage dashboard.

### Inline content not showing

* Confirm the `<digia>` tag includes `type="inline"` and a `placement` attribute.
* Ensure `placement` in the `<digia>` tag matches `DigiaSlot('placement_key')` or `DigiaSlotView app:placementKey` exactly (case-sensitive).
* Verify the slot exists on the currently visible screen.
* **Android XML**: Ensure a `DigiaHostView` is mounted in the same window before `DigiaSlotView` renders.
* **React Native**: Confirm `DigiaSlotView` is imported from `@digia-engage/webengage` and the `placementKey` exactly matches the `placement` in the campaign tag.

### Screen-triggered campaign not firing

* Add `DigiaNavigatorObserver()` to `navigatorObservers` (Flutter).
* Call `Digia.setCurrentScreen(...)` on navigation changes (Android Compose: `navController.addOnDestinationChangedListener`).
* **Android XML / Views**: Call `digiaScreen("screen_name")` from `Activity.onResume()` or `Fragment.onResume()`.
* For unnamed routes, call `Digia.setCurrentScreen('screen_name')` manually.
* **iOS (Swift)**: On tab/route changes, call `Digia.setCurrentScreen("screen_name")` from your navigation layer.
* **React Native**: Wire navigation change events (React Navigation / Expo Router) to `Digia.setCurrentScreen(routeName)`.

### WebEngage SDK not initialized (Android)

* Ensure `registerActivityLifecycleCallbacks(WebEngageActivityLifeCycleCallbacks(this, webEngageConfig))` is called in `Application.onCreate()` before `Digia.register(...)`.
* Verify the WebEngage license key is correctly set in `WebEngageConfig.Builder().setWebEngageKey(...)` and matches your WebEngage dashboard.

***

## Official WebEngage References

* [Flutter SDK](https://docs.webengage.com/docs/flutter-getting-started)
* [Android Integration Guide](https://docs.webengage.com/docs/android-integration-guide)
* [iOS Integration Guide](https://docs.webengage.com/docs/ios-integration-guide)
* [React Native Getting Started](https://docs.webengage.com/docs/react-native-getting-started)
