Digia Engage — Flutter SDK

pub.dev Flutter License Documentation

Digia Engage is the Flutter SDK for displaying in-app campaigns powered by Digia Studio. It connects to your Customer Engagement Platform (MoEngage, CleverTap, etc.) and renders server-driven in-app experiences — dialogs, bottom sheets, and inline widgets — without shipping a new app build.


How It Works

  1. Your CEP (e.g. MoEngage) sends a campaign trigger to the device.
  2. The DigiaCEPPlugin adapter receives the payload and hands it to the SDK.
  3. The SDK routes it to the right renderer:
    • Modal (dialog / bottom sheet) → rendered by DigiaHost
    • Inline (banner / card) → rendered by DigiaSlot
  4. The component is built from a server-driven layout defined in Digia Studio — no client-side code changes needed.

Installation

dependencies:
  digia_engage: ^1.6.0

Quick Start

1. Initialize

Call once in main() before runApp().

await Digia.initialize(
  DigiaConfig(
    apiKey: 'YOUR_API_KEY',
  ),
);

2. Register your CEP plugin

After your CEP SDK is ready, register its adapter:

Digia.register(CEPPlugin(instance: cepInstance));

3. Add DigiaHost and DigiaNavigatorObserver

Wrap your MaterialApp so the SDK can show modal overlays and track screens:

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

navigatorKey: DigiaHost.navigatorKey is required. DigiaHost sits in MaterialApp.builder which is above the Navigator in the widget tree. Without this key the SDK cannot resolve a navigator context to show modals.

4. Add DigiaSlot where inline content should appear

Place a slot anywhere in your page layout. Use the same placementKey that was configured in Digia Studio.

Column(
  children: [
    DigiaSlot('home_hero_banner'),
    // ... rest of your page
  ],
)

1.1.0+ — Inline payloads must include "type": "inline" and "placementKey": "<key>". Payloads missing both type and command are dropped with a warning.


API Reference

Digia

Static facade — the single entry point for all SDK calls.

Method Description
Digia.initialize(config) Boot the SDK. Call once in main(), await before runApp().
Digia.register(plugin) Attach a CEP plugin adapter (MoEngage, CleverTap, etc.).
Digia.setCurrentScreen(name) Manually report the current screen name to the CEP.

DigiaConfig

Property Type Description
apiKey String Required. Environment-specific API key from the Digia dashboard.
environment DigiaEnvironment Target environment. Defaults to DigiaEnvironment.production (.sandbox for testing).
logLevel DigiaLogLevel Log verbosity. Defaults to DigiaLogLevel.error (.none / .verbose).
baseUrl String? Optional override for the engage API host. Derived from environment when null.
fontFamily String? Optional global font family applied to all Digia-rendered text.
onAction EngageActionInterceptor? Optional hook to intercept navigation actions (open URL / deep link). Return true to handle the link yourself.

DigiaHost

Mount once in MaterialApp.builder. Automatically renders modal campaigns (dialog / bottom sheet) when triggered by the CEP.

MaterialApp(
  navigatorKey: DigiaHost.navigatorKey,   // required
  navigatorObservers: [DigiaNavigatorObserver()],
  builder: (context, child) => DigiaHost(child: child!),
)

Behavior:

Campaign type Handled by
dialog DigiaHost — shows as a dialog
bottomsheet DigiaHost — shows as a modal bottom sheet
inline DigiaSlot — not handled by DigiaHost

DigiaSlot

Renders inline campaign content at a named placement position. Collapses to nothing when no campaign is active.

DigiaSlot('placement_key')

Lifecycle:

Event Behavior
Slot mounts, campaign already exists Renders immediately and fires an impression
New campaign arrives for this placement Rebuilds and fires impression for the new payload
Server invalidates the campaign Slot collapses to SizedBox.shrink()
User dismisses via a close CTA Fires dismiss event, slot collapses
Page navigates away / disposes Campaign stays in memory — reappears on return

DigiaNavigatorObserver

Automatically reports the current route name to the CEP as a screen-change event. Add it to navigatorObservers and no manual setCurrentScreen calls are needed.

navigatorObservers: [DigiaNavigatorObserver()]

CEP Plugin Interface

To connect a new CEP, implement DigiaCEPPlugin:

class MyCEPPlugin implements DigiaCEPPlugin {
  @override
  String get identifier => 'my_cep';

  @override
  void setup(DigiaCEPDelegate delegate) {
    // Subscribe to in-app events from your CEP SDK and pass payloads
    // to delegate.onExperienceReady(payload)
  }

  @override
  void teardown() { /* clean up subscriptions */ }

  @override
  void notifyEvent(DigiaExperienceEvent event, CEPTriggerPayload payload) {
    // Forward impression/dismiss events back to your CEP
  }

  @override
  void forwardScreen(String screenName) {
    // Forward screen name to your CEP
  }
}

Then register it:

Digia.register(MyCEPPlugin());

Experience Events

The SDK fires two events during a campaign lifecycle, forwarded to your CEP plugin via notifyEvent:

Event When
ExperienceImpressed The first time a campaign renders (modal shown / slot built)
ExperienceDismissed The user explicitly closes the campaign

License

This project is licensed under the Business Source License 1.1 (BSL 1.1) - see the LICENSE file for details. The BSL 1.1 allows personal and commercial use with certain restrictions around competing platforms. On August 5, 2029, the license will automatically convert to Apache License 2.0.

For commercial licensing inquiries or exceptions, please contact admin@digia.tech.

Documentation

Full documentation is available at docs.digia.tech:

Support

Libraries

api/digia
api/interfaces/digia_cep_delegate
api/interfaces/digia_cep_plugin
api/internal/action/engage_action
api/internal/action/engage_action_context
api/internal/action/engage_action_handler
api/internal/action/engage_action_parser
api/internal/campaign/campaign_fetcher
api/internal/campaign/campaign_model
api/internal/campaign/campaign_store
api/internal/campaign/inline_story_config
api/internal/campaign/json_util
Safe JSON readers mirroring Android's JSONObject.optX helpers.
api/internal/digia_endpoints
api/internal/digia_instance
api/internal/digia_overlay_controller
api/internal/engage_fonts
api/internal/event/cep_plugin_sink
api/internal/event/digia_analytics_sink
api/internal/event/dwell_tracker
api/internal/event/engage_analytics_event
api/internal/event/engage_event_emitter
api/internal/expr_evaluator
api/internal/guide/anchor_registry
api/internal/guide/guide_action_button
api/internal/guide/guide_bubble
api/internal/guide/guide_color
api/internal/guide/guide_config_model
api/internal/guide/guide_orchestrator
api/internal/guide/guide_showcase_manager
api/internal/nudge/nudge_box_decorator
api/internal/nudge/nudge_config
api/internal/nudge/nudge_content
api/internal/nudge/nudge_node_renderer
api/internal/nudge/nudge_parser
api/internal/nudge/nudge_presentation
api/internal/nudge/nudge_presenter
api/internal/nudge/nudge_view
api/internal/sdk_state
api/internal/survey/submission_reporter
api/internal/survey/survey_config
Survey schema delivered by the getCampaigns API for a campaignType == "survey" campaign. A 1:1 Dart port of the Android SurveyConfigModel.kt (itself a mirror of the dashboard Survey type).
api/internal/survey/survey_controller
api/internal/survey/survey_logic_handler
api/internal/survey/survey_orchestrator
api/internal/survey/ui/survey_question_widgets
api/internal/survey/ui/survey_renderer
api/internal/survey/ui/survey_tokens
api/internal/variable_scope
api/models/analytics_config
api/models/cep_trigger_payload
api/models/diagnostic_report
api/models/digia_config
api/models/digia_experience_event
api/models/variable_schema
api/widgets/digia_anchor
api/widgets/digia_host
api/widgets/digia_inline_story
api/widgets/digia_navigator_observer
api/widgets/digia_slot
api/widgets/story/digia_story_overlay
digia_engage