Digia as Your CEP
Digia can drive your in-app campaigns on its own. Each campaign carries its own trigger and priority, authored in the Digia Engage Dashboard, and the SDK decides which campaign fires, when, and in what order — rendered natively on the device.
You set where and when a campaign appears in the same place you design it, enable managed campaigns with a single call, and wire screen tracking. That is the whole integration.
Reach for it whenever Digia should own delivery end to end — an onboarding guide on first launch, a promo nudge on the home screen, or an inline story in your feed.
React Native today. Managed campaigns ship for React Native first; Android, iOS and Flutter support is on the way.
Prerequisites
- Digia Access Key — Log in to the Digia Engage Dashboard, open your project, and copy your key from Settings → App Settings.
- Project CEP set to Digia — In Settings → App Settings, set CEP integration to Digia. This adds the Trigger step to the campaign wizard. You can also choose it when you create the project.
- No extra dependencies — There is nothing else to install or initialize.
Minimum Supported Versions
- Environment: React Native
0.83+, React19.2+ - Digia package:
@digia-engage/core
Install
npm install @digia-engage/core@2.22.0
That is the whole dependency list — managed campaigns need only the core package.
Initialize
Two calls: initialize the SDK, then enable managed campaigns.
import { useEffect } from 'react';
import { Digia } from '@digia-engage/core';
export function RootApp() {
useEffect(() => {
(async () => {
// 1. Initialize Digia once at startup.
await Digia.initialize({
apiKey: 'YOUR_ACCESS_KEY',
});
// 2. Let Digia decide what fires, from each campaign's trigger and priority.
Digia.enableManagedCampaigns();
// 3. Wire screen tracking to your navigation library (see below) so
// screen-triggered campaigns fire on the right screen.
})().catch(console.error);
}, []);
return <AppNavigator />;
}
enableManagedCampaigns() is order-independent — calling it before initialize() resolves is
fine, and triggering begins as soon as campaigns have loaded — and idempotent, so a double
call still fires each campaign once.
Reporting the current screen
Digia.setCurrentScreen(name) is what makes On screen triggers work, and the names you report
are exactly the ones campaign creators pick from in the dashboard.
A small hook keeps this to one line per screen. With React Navigation, useFocusEffect re-reports
every time a screen regains focus — returning to a tab, not just first mount:
import { useFocusEffect } from '@react-navigation/native';
import { useCallback } from 'react';
import { Digia } from '@digia-engage/core';
export function useScreenTracking(screenName: string) {
useFocusEffect(
useCallback(() => {
Digia.setCurrentScreen(screenName);
}, [screenName]),
);
}
Call it once in each screen — the name must match the campaign's On screen trigger exactly (it is case-sensitive):
export function HomeScreen() {
useScreenTracking('home');
return /* … */;
}
Expo Router: import useFocusEffect from expo-router instead — everything else is identical.
See Reporting the Current Screen for more navigation-library snippets, including GoRouter, Expo Router, tab bars, and apps with no navigation library.
Advanced configuration
Digia.initialize() accepts more fields that shape SDK behaviour:
await Digia.initialize({
apiKey: 'YOUR_ACCESS_KEY',
logLevel: 'error', // 'none' | 'error' | 'verbose' — defaults to 'error'
actionHandlers: {
// Own how specific campaign actions are handled. A registered handler
// fully replaces the SDK's default behavior for that action.
customKV: (payload) => {/* run an app-owned key-value command */},
deepLink: (url) => {/* navigate in-app */},
openURL: (url) => {/* present a web URL */},
},
linking: {
inAppBrowser: defaultInAppBrowser, // Required for open_url with presentation: 'in_app'
},
});
See Campaign Actions for the full list of action types, deep link URL format, and the in-app browser adapter.
Experience types
A campaign's type decides what renders and which app surface hosts it. All four are supported:
| Experience | Digia component | Renders as |
|---|---|---|
| Nudge | DigiaHost | Overlay — bottom sheet or dialog above your app |
| Guide | DigiaAnchorView + DigiaHost | Step-by-step tooltip / spotlight anchored to a UI element |
| Survey | DigiaHost | Multi-step questionnaire overlay |
| Inline | DigiaSlotView | Content embedded in your layout — banner, card or story |
Every type is triggered the same way — by App start or On screen, set per campaign in the dashboard (see section 6). Mount the surfaces for the types your campaign creators plan to use; the next section shows each.
Register your app surfaces
Campaigns need somewhere to render. Which surfaces you add depends on the experience types in play.
Nudges, surveys and guides all render through DigiaHost — mount it once at the app root, as
the topmost layer:
import { View } from 'react-native';
import { DigiaHost } from '@digia-engage/core';
export default function RootLayout() {
return (
<View style={{ flex: 1 }}>
<AppNavigator />
{/* Mounted last, so it sits on the top layer — guide overlays paint above your app UI. */}
<DigiaHost />
</View>
);
}
Keep DigiaHost as the last child of your root view. Being last puts it on the topmost layer,
so guide overlays — the tooltips and spotlights, which render in JS — paint above your app content
and appear correctly. Mount it higher up the tree and your app UI can cover them.
Nudges render as overlays — a bottom sheet or dialog above your app — and need nothing beyond
DigiaHost. Design the nudge in the dashboard, give it a trigger, and it appears when the trigger
fires.
Surveys are multi-step questionnaires shown as overlays in the same host, again with no extra surface. Build the survey in the dashboard, give it a trigger, and it appears just like a nudge.
Guides additionally need each anchorable element wrapped with a unique anchorKey — the same
key the campaign's step targets in the dashboard:
import { DigiaAnchorView } from '@digia-engage/core';
<DigiaAnchorView anchorKey="buy_now_button">
<BuyNowButton />
</DigiaAnchorView>;
Inline content needs a slot wherever it should appear. The placementKey is what campaign
creators pick in the dashboard, so share the names you add:
import { DigiaSlotView } from '@digia-engage/core';
<DigiaSlotView placementKey="home_top" />;
See Managing Inline Content for sizing and clearing content.
Author the trigger in the dashboard
With the project's CEP set to Digia, the campaign wizard gains a Trigger step between Setup and Choose UI. It asks two things.
Trigger
| Trigger | Fires |
|---|---|
| App start | Once each time the app launches, as soon as the SDK is ready. |
| On screen | Every time the user opens one of the screens you choose. |
The screens you pick for an On screen trigger are also the screens the campaign is allowed to appear on. That is why this project needs no separate Target screens field on the Setup step — the trigger already says where the campaign belongs.
Priority
High, Normal (default) or Low. It decides the order when several campaigns become eligible at
the same moment — see the next section.
Only active campaigns are fetched by the SDK. A campaign left in draft never fires, whatever
its trigger says.
How Digia chooses what to show
When a trigger fires, more than one campaign can qualify at once — three campaigns with an App start trigger, for instance. Digia shows them in a deliberate order, one at a time.
1. Eligible campaigns are ordered.
- Priority —
High, thenNormal, thenLow. - Most recent first — among equal priority, the campaign created last wins, as the more current message.
2. They're shown one at a time. A nudge, guide or survey owns the whole screen surface, so the next one appears only once the previous is dismissed. The rest wait their turn.
3. Inline never waits. Inline campaigns live in their own slot, contend with nothing, and appear immediately — even while a nudge is on screen.
A campaign already on screen is never re-triggered. Once dismissed, it can fire again the next time its trigger matches — so an On screen campaign returns on a repeat visit, subject to the frequency cap set on the Delivery step.
Test your integration
Verify end-to-end before you ship:
- Confirm CEP integration is set to Digia — otherwise campaigns carry no trigger (Settings → App Settings).
- Confirm the calls run once at startup —
Digia.initialize(...)thenDigia.enableManagedCampaigns(), before your first screen. - Mount
<DigiaHost />once at the app root for nudges, surveys and guides. - Create an App start campaign — a simple nudge is easiest — mark it active, and relaunch the app. It should appear as soon as the SDK is ready.
- Create an On screen campaign and confirm it fires when you navigate to its screen. Check that
the screen names in the Trigger step match exactly what your app passes to
setCurrentScreen(they are case-sensitive). - Place a
DigiaSlotViewwith a matchingplacementKeyand confirm inline content renders. - Watch the verbose log — set
logLevel: 'verbose'and confirm the campaign store loads and each trigger names the campaigns it chose.
Turning it off
Digia.disableManagedCampaigns();
Stops triggering and clears anything queued; campaigns already on screen are left alone. Handy on logout, or any time you want Digia to stop delivering campaigns.
Troubleshooting
Nothing fires at all
-
Is
Digia.enableManagedCampaigns()actually called? Without it, Digia does not fire campaigns on its own, so nothing appears. -
Is the project's CEP integration set to Digia? That is what gives each campaign a trigger to fire on.
-
Is the campaign active?
-
Turn on
logLevel: 'verbose'inDigia.initialize. You should see the campaign store load and then a line naming the campaigns chosen for each trigger:[Digia] loaded 2 campaign(s): [home_story, welcome_nudge][Digia] [triggers] trigger app_start → [welcome_nudge(high), home_story(normal)]
A campaign is chosen but doesn't appear
The verbose log shows why:
[Digia] Campaign dropped by native: campaign_key=home_story … current_screen=account
Usual causes, in order:
- Screen mismatch. The campaign's screens don't include the screen the user is on. Confirm the
names in the Trigger step match exactly what your app passes to
setCurrentScreen— they are case-sensitive. setCurrentScreenis never called, so Digia thinks the user is nowhere and every screen-scoped campaign waits.- Frequency cap reached for that campaign (Delivery step).
- Incomplete content — an inline story with no media items, for example — is rejected when the SDK parses it.
An inline campaign fires but shows nothing
The slot isn't on screen. <DigiaSlotView placementKey="…" /> must be mounted, and its
placementKey must match the campaign's slot key exactly.
A screen trigger never fires
Compare the screen name your app reports against the campaign's list, character for character. Add
a temporary log in your navigation listener to see exactly what is passed to setCurrentScreen.
See also
- Reporting the Current Screen — wiring
setCurrentScreento your navigation library. - Screen Targeting — scoping campaigns to specific screens.
- Managing Inline Content — sizing and clearing inline slots.
- Campaign Actions — action types, deep links, and the in-app browser adapter.
- User Identity — attach a logged-in user to Digia's analytics with
Digia.setUserId/clearUserId.