Digia Engage — Flutter SDK

pub.flutter-io.cn 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

flutter pub add digia_engage

Quick Start

1. Initialize

Call once in main() before runApp().

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

Local Test Kit

Keep arbitrary hosts out of production configuration. A debug/noop harness can install a mock server root before normal initialization; the root excludes /api/v1.

DigiaTestKit.overrideBaseUrl('http://10.0.2.2:9871');
await Digia.initialize(DigiaConfig(apiKey: 'local-testkit'));

The value must be an HTTP(S) origin with no path, credentials, query, or fragment, and it cannot change after initialization. A dedicated release-mode test build can pass allowInRelease: true; ordinary release builds reject the override.

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(
  navigatorObservers: [DigiaNavigatorObserver()],
  builder: (context, child) => DigiaHost(child: child!),
  home: const MyHomePage(),
)

DigiaHost sits in MaterialApp.builder, above the Navigator, so the SDK needs the app's navigator to show modals. DigiaNavigatorObserver provides it. If you already pass your own GlobalKey<NavigatorState> to MaterialApp.navigatorKey, you can also hand the same key to the host: DigiaHost(navigatorKey: myNavigatorKey, child: child!). Without either, a nudge is dropped (logged) instead of shown. Mount exactly one DigiaHost.

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.
Digia.setThemeMode(mode) Select the light, dark, or automatic device theme for Campaign Canvas colors. Already-mounted Canvas content updates locally.

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).
fontFamily String? Optional global font family applied to all Digia-rendered text.
themeMode DigiaThemeMode Campaign Canvas color theme. Defaults to DigiaThemeMode.auto; light and dark can be selected explicitly.
actionHandlers DigiaActionHandlers Typed handlers for Custom KV, deep-link, and open-URL actions. Registered handlers own their actions; links otherwise use Flutter's launcher.

Handlers can also be replaced at runtime with Digia.setCustomKVHandler, Digia.setDeepLinkHandler, and Digia.setOpenURLHandler.

The host may change Campaign Canvas colors at runtime without refetching or reparsing campaigns:

Digia.setThemeMode(DigiaThemeMode.dark);

In DigiaThemeMode.auto, Digia follows platform-brightness changes locally.

Register the required faces under one Flutter family in pubspec.yaml, then pass that family name:

DigiaConfig(
  apiKey: 'dev_xxxx',
  fontFamily: 'Inter',
)

DigiaHost

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

MaterialApp(
  navigatorObservers: [DigiaNavigatorObserver()],   // required: gives the host the navigator
  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/cep
The Core ↔ CEP interface, v2.
api/cep/campaign_presentation
api/cep/digia_cep_host
api/cep/digia_cep_plugin
api/cep/pending_payload_buffer
api/cep/presentation_controller
api/cep/presentation_outcome
api/cep/presentation_signal
api/digia
api/digia_test_kit
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/anchorless/anchorless_target_layer
api/internal/bottom_sheet_drag_dismiss
api/internal/campaign/campaign_color
api/internal/campaign/campaign_fetcher
api/internal/campaign/campaign_model
api/internal/campaign/campaign_store
api/internal/campaign/design_token_catalog
api/internal/campaign/inline_banner_config
api/internal/campaign/inline_canvas_config
api/internal/campaign/inline_story_config
api/internal/campaign/inline_story_thumbnail_playback
api/internal/campaign/json_util
Safe JSON readers mirroring Android's JSONObject.optX helpers.
api/internal/campaign/routing_verdict
api/internal/campaign/server_time_clock
api/internal/campaign/surface_rule
The surface rule: nothing new ever replaces what's already on screen, and its live-test exception (ai_docs/surface-rule-plan.md §2.1, §2.2).
api/internal/campaign_font_weight
api/internal/canvas/campaign_canvas_action_scope
api/internal/canvas/campaign_canvas_analytics
api/internal/canvas/campaign_canvas_model
api/internal/canvas/campaign_canvas_paint
api/internal/canvas/campaign_canvas_parser
api/internal/canvas/campaign_canvas_renderer
api/internal/canvas/campaign_canvas_scale
api/internal/canvas/campaign_canvas_view
api/internal/canvas/campaign_color_resolver
api/internal/canvas/campaign_timer_scope
api/internal/canvas/canvas_close_icon
api/internal/cep/delivery_timeline_observer
api/internal/cep/presentation_coordinator
api/internal/digia_endpoints
api/internal/digia_overlay_controller
api/internal/divider_with_pattern
api/internal/engage_fonts
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/event/presentation_sink
api/internal/expr_evaluator
api/internal/floater_story/floater_story_config
api/internal/floater_story/floater_story_orchestrator
api/internal/floater_story/floater_story_renderer
api/internal/frequency/frequency_evaluator
api/internal/frequency/frequency_manager
api/internal/frequency/frequency_policy
Typed frequency-capping policy + state models.
api/internal/guide/anchor_registry
api/internal/guide/digia_guide_target
api/internal/guide/guide_canvas_view
api/internal/guide/guide_color
api/internal/guide/guide_config_model
api/internal/guide/guide_orchestrator
api/internal/guide/guide_showcase_manager
api/internal/image_placeholder
api/internal/media_load_failure
api/internal/network_client
api/internal/nudge/canvas_nudge_presentation
api/internal/nudge/nudge_config
api/internal/nudge/nudge_parser
api/internal/nudge/nudge_presentation
api/internal/nudge/nudge_presenter
api/internal/pip/pip_config
Typed config for a pip campaign — a small, draggable media window scoped to one screen that expands to full screen on tap.
api/internal/pip/pip_orchestrator
api/internal/pip/pip_renderer
api/internal/sdk_instance
api/internal/sdk_services
api/internal/sdk_state
api/internal/survey/canvas/canvas_survey_answer_validator
api/internal/survey/canvas/canvas_survey_config
api/internal/survey/canvas/canvas_survey_config_parser
api/internal/survey/canvas/canvas_survey_controller
api/internal/survey/canvas/canvas_survey_document_parser
api/internal/survey/canvas/canvas_survey_flow
api/internal/survey/canvas/canvas_survey_flow_engine
api/internal/survey/canvas/canvas_survey_host_elements
api/internal/survey/canvas/canvas_survey_shared_ui
api/internal/survey/canvas/ui/canvas_survey_answer_input_registry
api/internal/survey/canvas/ui/canvas_survey_answer_metrics
api/internal/survey/canvas/ui/canvas_survey_choice_input
api/internal/survey/canvas/ui/canvas_survey_close_button
api/internal/survey/canvas/ui/canvas_survey_field_input
api/internal/survey/canvas/ui/canvas_survey_managed_host_widgets
api/internal/survey/canvas/ui/canvas_survey_modal_bottom_sheet_route
api/internal/survey/canvas/ui/canvas_survey_panel
api/internal/survey/canvas/ui/canvas_survey_route
api/internal/survey/canvas/ui/canvas_survey_scale_input
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_logic_handler
api/internal/survey/survey_orchestrator
api/internal/survey/ui/survey_renderer
api/internal/test_view
api/internal/variable_scope
api/models/analytics_config
api/models/cep_trigger_payload
api/models/digia_action_handlers
api/models/digia_config
api/models/digia_experience_event
api/models/variable_schema
api/widgets/digia_anchor
api/widgets/digia_campaign_timeline_screen
api/widgets/digia_debug_settings_screen
api/widgets/digia_host
api/widgets/digia_inline_banner
api/widgets/digia_inline_canvas
api/widgets/digia_inline_story
api/widgets/digia_navigator_observer
api/widgets/digia_recorded_session_screen
api/widgets/digia_recording_badge
api/widgets/digia_slot
api/widgets/slot_exposure
api/widgets/story/digia_canvas_story_overlay
api/widgets/story/digia_story_overlay
api/widgets/story/story_card_thumbnail
api/widgets/story/story_media_fit
api/widgets/story/story_thumbnail_placeholder
api/widgets/story/story_thumbnail_video
api/widgets/story/story_video_playback
digia_engage
logging
The Digia SDK's logging surface.
testing/cep
Test support for the v2 core ↔ CEP contract.