# Digia Moengage Integration

***

The Digia MoEngage plugin intercepts **MoEngage self-handled 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 Dashboard Account**: Ensure you have an active MoEngage workspace with access to your App/Account IDs.
* **MoEngage SDK**: Installed and initialized (see [Flutter](https://developers.moengage.com/hc/en-us/articles/20661421128084-Getting-Started-with-Flutter-SDK), [Android](https://developers.moengage.com/hc/en-us/categories/360006147431-Android-SDK), [iOS](https://developers.moengage.com/hc/en-us/articles/4403900743828-SDK-Integration), or [React Native](https://developers.moengage.com/hc/en-us/articles/22105190881044-Getting-Started-with-React-Native-SDK#h_01HEJAHP5W49AASNSHF5614AHP) 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.0</code><br><code>digia\_moengage\_plugin: ^1.0.0</code><br><code>moengage\_flutter: ^10.5.0</code></p>                                                        |
| **Android**      | `minSdk 24`                                                       | <p><code>tech.digia:engage:1.1.0</code><br><code>tech.digia:engage-moengage:1.1.0</code><br><code>com.moengage:moe-android-sdk:14.06.00</code><br><code>com.moengage:inapp:9.9.1</code></p> |
| **iOS (Swift)**  | iOS `16+`                                                         | <p><code>DigiaEngage: 1.0.0</code><br><code>DigiaMoEngage: 1.0.0</code></p>                                                                                                                 |
| **React Native** | React Native `0.73+`                                              | <p><code>@digia-engage/core: 1.1.1</code><br><code>@digia-engage/moengage: 1.1.0</code><br><code>react-native-moengage: installed</code></p>                                                |

***

## 2. Install

> **Note:** We assume the core MoEngage 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_moengage_plugin
```

{% endtab %}

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

```kotlin
dependencies {
  implementation("tech.digia:engage:1.1.0")
  implementation("tech.digia:engage-moengage:1.1.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_moengage_iOS.git", exact: "1.0.0"),
],
```

Then add these products to your app target dependencies:

* `DigiaEngage`
* `DigiaMoEngage`
  {% endtab %}

{% tab title="React Native" %}
Install the Digia packages:

```bash
npm install @digia-engage/core@1.1.1 @digia-engage/moengage@1.1.0
```

{% endtab %}
{% endtabs %}

***

## 3. Initialize Digia with MoEngage

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

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

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

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

  // 1. MoEngage SDK — initialise activates the native SDK already configured as a prerequisite.
  final moEngage = MoEngageFlutter('YOUR_MOENGAGE_APP_ID');
  moEngage.initialise();

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

  // 3. Register the Digia MoEngage plugin.
  Digia.register(DigiaMoEngagePlugin(instance: moEngage));
  runApp(const MyApp());
}
```

{% endtab %}

{% tab title="Android" %}

```kotlin
import android.app.Application
import com.digia.engage.Digia
import com.digia.engage.DigiaConfig
import com.digia.engage.moengage.DigiaMoEngagePlugin

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

        // 1. MoEngage SDK — initialized as a prerequisite.
        // MoEngage.initialiseDefaultInstance(moEngage)

        // 2. Initialize Digia before registering any CEP plugin.
        Digia.initialize(
            context = applicationContext,
            config = DigiaConfig(apiKey = "YOUR_ACCESS_KEY"),
        )

        // 3. Register the Digia MoEngage plugin. Context is required to resolve the MoEngage instance.
        Digia.register(DigiaMoEngagePlugin(applicationContext))
    }
}
```

{% endtab %}

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

```swift
import SwiftUI
import DigiaEngage
import DigiaMoEngage

@main
struct MyApp: App {
    init() {
        // 1. MoEngage SDK — initialized as a prerequisite.
        // MoEngage.sharedInstance.initializeDefaultInstance(...)

        // 2. Initialize Digia before registering any CEP plugin.
        Task {
            do {
                try await Digia.initialize(DigiaConfig(apiKey: "YOUR_ACCESS_KEY"))

                // 3. Register the Digia MoEngage plugin.
                Digia.register(DigiaMoEngagePlugin())
            } catch { }
        }
    }

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

{% endtab %}

{% tab title="React Native" %}

```tsx
import { useEffect } from 'react';
import ReactMoE from 'react-native-moengage';
import { Digia } from '@digia-engage/core';
import { DigiaMoEngagePlugin, createMoEngageClient } from '@digia-engage/moengage';

export function RootApp() {
  useEffect(() => {
    (async () => {
      // 1. MoEngage SDK — activate the JS bridge.
      ReactMoE.initialize('YOUR_MOENGAGE_WORKSPACE_ID');

      // 2. Initialize Digia before registering any CEP plugin.
      await Digia.initialize({
        apiKey: 'YOUR_ACCESS_KEY',
      });

      // 3. Register the Digia MoEngage plugin.
      Digia.register(
        new DigiaMoEngagePlugin({
          moEngage: createMoEngageClient(ReactMoE),
        })
      );
    })().catch(console.error);
  }, []);

  return <AppNavigator />;
}
```

{% endtab %}
{% endtabs %}

***

## 4. How Digia Maps to MoEngage Campaigns

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

```mermaid
flowchart TD
    Trigger[MoEngage Campaign Trigger]
    SDK[MoEngage SDK]
    Plugin[Digia MoEngage Plugin]
    Runtime[digia_engage runtime]
    UI[Campaign UI<br>native widgets from Digia Studio]

    Trigger --> SDK
    SDK -- "Self-handled in-app 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

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

MoEngage supports a delivery mode called **Self-Handled In-App Campaigns** — instead of MoEngage rendering its own campaign UI, the SDK delivers the campaign payload to your app code. The Digia MoEngage plugin registers a self-handled in-app listener that intercepts this payload, maps it to a `SHOW_BOTTOM_SHEET` or `SHOW_DIALOG` command, and delegates rendering to Digia's runtime. **Without setting the campaign template type to Self Handled in the MoEngage dashboard, the payload will not be delivered to the plugin.**

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

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

1. Log in to the **MoEngage dashboard** and go to **Engage → In-App (NATIV)**.
2. Click **Create Campaign** and give it a name.
3. Set the **Template type** to **Self Handled**.
4. Configure the event trigger, audience, and schedule as required.
5. In the **Campaign data / Key-Value Pairs** field, enter the Digia payload JSON (see [Trigger a Nudge from MoEngage](#trigger-a-nudge-from-moengage) below).

See [MoEngage Self-Handled In-App](https://help.moengage.com/hc/en-us/articles/360051330591-Self-Handled-In-App-Template#h_01HP6KGBAVZDEV75BEFKRZ2M7R).

### 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" %}

```tsx
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { DigiaHostView } from '@digia-engage/core';
import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <View style={styles.root}>
      {/* Host overlay for bottom sheets/dialogs above the app UI */}
      <DigiaHostView style={StyleSheet.absoluteFill} />
      <Stack />
    </View>
  );
}

const styles = StyleSheet.create({
  root: { flex: 1 },
});
```

{% endtab %}
{% endtabs %}

### Trigger a Nudge from MoEngage

Create a Self-Handled in-app campaign in MoEngage. In the campaign data payload, fill in the following fields:

| Field     | Required | Example value         | Description                                                                             |
| --------- | -------- | --------------------- | --------------------------------------------------------------------------------------- |
| `command` | Yes      | `SHOW_BOTTOM_SHEET`   | `SHOW_BOTTOM_SHEET` or `SHOW_DIALOG`.                                                   |
| `viewId`  | Yes      | `promo_offer_sheet`   | Digia page slug. See [Finding Slugs](/studio-workspace/builder-tool/finding-slugs.md).  |
| `args`    | No       | `{"coupon":"SAVE20"}` | Enter as a raw JSON string in the text field. Available in Digia page logic at runtime. |

> **`args` format:** Enter the value as plain JSON text directly in the field — e.g., `{"coupon":"SAVE20"}`. Do not wrap it in outer quotes. The plugin JSON-decodes the string 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 `placementId` in the MoEngage campaign payload. When a Self-Handled in-app campaign with `SHOW_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 Self-Handled 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 MoEngage 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 MoEngage 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(placementKey: "home_hero_banner")
                ProductCarousel()
                DigiaSlot(placementKey: "product_offers")
                RecommendationList()
            }
            .padding()
        }
    }
}
```

{% endtab %}

{% tab title="React Native" %}

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

export function HomeScreen() {
  return (
    <ScrollView>
      <DigiaSlotView
        placementKey="home_hero_banner"
        style={{ width: '100%', height: 180 }}
      />

      <ProductCarousel />

      <DigiaSlotView
        placementKey="product_offers"
        style={{ width: '100%', height: 140 }}
      />

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

{% endtab %}
{% endtabs %}

### Serve Inline Content from MoEngage

For Self-Handled in-app campaigns, set the payload `type` to `inline` and provide the `placementKey` and `viewId`:

```json
{
  "type": "inline",
  "placementKey": "home_hero_banner",
  "viewId": "home_hero_banner-v2N8"
}
```

| Field          | Required | Description                                                                                                         |
| -------------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `type`         | Yes      | Must be `inline` for inline slots.                                                                                  |
| `placementKey` | Yes      | Must match the `DigiaSlot` / `DigiaSlotView` placement key in your app code.                                        |
| `viewId`       | Yes      | Digia component or page slug. See [Finding Slugs](/studio-workspace/builder-tool/finding-slugs.md) for slug lookup. |

See [Finding Slugs](/studio-workspace/builder-tool/finding-slugs.md) for slug lookup.

***

## 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(DigiaMoEngagePlugin(...))`, 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, `DigiaHostView` is to be used.
3. **Set campaign to Self Handled** — ensure the MoEngage in-app campaign template type is **Self Handled** in the MoEngage dashboard (see [Self-Handled In-App Campaigns: Set Up in Dashboard](#self-handled-in-app-campaigns-set-up-in-dashboard)).
4. **Create a test campaign** — create a Self-Handled 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 a Self-Handled in-app campaign with `SHOW_INLINE` and a matching `placementId`, 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 shape is platform-specific, but always includes `isHealthy` plus diagnostic metadata.

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

```dart
final moEngage = MoEngageFlutter('YOUR_MOENGAGE_APP_ID');
moEngage.initialise();

final plugin = DigiaMoEngagePlugin(instance: moEngage);
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 (Jetpack Compose)" %}

```kotlin
val plugin = DigiaMoEngagePlugin(applicationContext)
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 = DigiaMoEngagePlugin()
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 MoEngage from 'react-native-moengage';
import { Digia } from '@digia-engage/core';
import { DigiaMoEngagePlugin, createMoEngageClient } from '@digia-engage/moengage';

const plugin = new DigiaMoEngagePlugin({
  moEngage: createMoEngageClient(MoEngage),
});

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

Reference open-source example apps for integration patterns:

* [medihub\_flutter](https://github.com/Digia-Technology-Private-Limited/medihub_flutter)
* [medihub\_android](https://github.com/Digia-Technology-Private-Limited/medihub_android)
* [medihub\_swift](https://github.com/Digia-Technology-Private-Limited/medihub_swift)
* [medihub\_rn](https://github.com/Digia-Technology-Private-Limited/medihub_rn)

### Campaign not rendering

* Confirm initialization order — `Digia.initialize(...)` then `Digia.register(DigiaMoEngagePlugin(...))`.
* Ensure the MoEngage campaign template type is set to **Self Handled** in the MoEngage dashboard.
* **iOS (Swift)**: Confirm `MoEngage.sharedInstance.initializeDefaultInstance(...)` runs at app start and `Info.plist` includes `MOEnvType`.
* **React Native**: Confirm `Digia.initialize(...)` and `Digia.register(new DigiaMoEngagePlugin(...))` are called once during app startup.
* 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.
* **React Native**: Ensure `DigiaHostView` is mounted once at app root and `app.json` contains MoEngage plugin credentials.
* Check `viewId` exactly matches the published Digia page slug (case-sensitive). See [Finding Slugs](/studio-workspace/builder-tool/finding-slugs.md).
* Verify campaign eligibility and trigger conditions in the MoEngage dashboard.

### Inline content not showing

* Confirm Self-Handled in-app payload includes `"type": "inline"` and a `placementKey` value.
* Ensure `placementKey` in payload 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**: Ensure `DigiaSlotView` has an explicit height/size in `style`, otherwise nothing is visible.

### 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)`.

### MoEngage SDK not initialized (Android)

* Ensure `MoEngage.initialise(moEngage)` is called in `Application.onCreate()` before `Digia.register(...)`.
* Verify MoEngage credentials are correctly configured per [MoEngage Android Quick Start](https://developers.moengage.com/hc/en-us/categories/360006147431-Android-SDK).

***

## Official MoEngage References

* [Flutter SDK](https://developers.moengage.com/hc/en-us/articles/20661421128084-Getting-Started-with-Flutter-SDK)
* [Android Quick Start](https://developers.moengage.com/hc/en-us/categories/360006147431-Android-SDK)
* [iOS SDK Integration](https://developers.moengage.com/hc/en-us/categories/360006471532-iOS-SDK)
* [React Native Quick Start Guide](https://developers.moengage.com/hc/en-us/categories/4404199274900-React-Native-SDK)


---

# Agent Instructions: 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:

```
GET https://docs.digia.tech/engagement-sdk/digia-engage/moengage-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
