For the complete documentation index, see llms.txt. This page is also available as Markdown.

Reporting the Current Screen

Where to call Digia.setCurrentScreen in every stack — navigator observers, per-screen hooks, router-specific recipes, and how to pick screen names that match your campaigns.

Digia.setCurrentScreen tells Digia Engage which screen the user is on. This page is the implementation guide: where the call goes in each stack, how to wire it to your navigation library, and how to choose names that actually match your campaigns.

For what screen targeting does and how a campaign owner uses it, see Screen Targeting.

setCurrentScreen is a Digia Engage core SDK capability. It behaves the same across React Native, Android, iOS, and Flutter, and across every integration — whether a CEP (CleverTap, MoEngage, WebEngage) drives delivery or Digia runs its own campaigns.


1. What the screen name drives

It is not only for targeting. One call feeds five things:

Consumer
What the screen name does

Campaign eligibility

A screen-targeted campaign renders only while the current screen is one of its targets.

Your CEP's screen view

Forwarded to CleverTap recordScreenView, MoEngage trackScreen, or WebEngage screen. This replaces your own CEP "record screen" call — you do not need both.

Analytics

Attached as screen_name to every impression Digia records.

Spotlight targeting

Anchorless spotlight steps match on the screen name.

Component capture (debug)

Anchors are skipped entirely while no screen is set, so capture comes back empty.

On Android and iOS the screen name also feeds screen-based frequency capping.


2. Automatic or manual?

There are two ways to report screens, and they are not equivalent.

Automatic (wire a navigator once)

Manual (call per screen)

Effort

One-time setup

One line per screen

Name you get

Whatever your router calls the route

Whatever you choose

Covers tab switches

No

Yes

Covers unnamed routes

No

Yes

Available on

Flutter, iOS

All stacks

Recommendation: manual, with a central constants file. It is one line per screen, it gives you names that match your dashboard, and it handles the cases a router cannot see. Reach for the automatic path when your app is large and already uses named routes that are exactly the strings your campaign owners type.

What ships today:

Stack
Automatic helper

Flutter

DigiaNavigatorObserver

iOS

DigiaNavigationScreenObserver (opt-in UINavigationControllerDelegate)

Android

None — call manually

React Native

None — call manually


3. Where the manual call goes

The subtle part is picking a lifecycle hook that fires on every arrival — not just the first mount. A screen the user navigates back to, or a tab they re-select, is still an arrival.

Use useFocusEffect, not useEffect. A tab screen stays mounted when you navigate away, so useEffect fires once and never again:

Then one line per screen:

Not using hooks? Digia is a plain singleton, so Digia.setCurrentScreen(...) works from componentDidMount, a navigation listener, a saga, or any non-React module. The hook is convenience, never the only path.

initState fires once per mount and not when the user navigates back — the screen underneath stays mounted the whole time. So initState alone silently under-reports.

Either let DigiaNavigatorObserver handle back-navigation (it reports the revealed route on pop), or report explicitly at each entry point:

For tabs and other cases the observer cannot see, see section 5.

Use onResume(), not onCreate(), so the call repeats when the user returns:

digiaScreen(...) is available on both Activity and Fragment.

In Compose, use the DigiaScreen composable:

Use viewDidAppear, not viewDidLoad:

In SwiftUI, call from .onAppear at the screen's root view only:


4. Set the screen before your triggers fire

This is the most common cause of a campaign that "just doesn't appear".

  • A campaign dropped for the wrong screen is not retried. If a campaign triggers while the current screen doesn't match, it is dropped there and then. It does not re-appear when the user later arrives on the targeted screen — your CEP has to trigger it again.

  • The screen is never remembered across launches. After every cold start it is unset, and while it is unset every screen-targeted campaign is dropped.

So report the first screen as early as you can — right after Digia.initialize(...), or from your first screen's arrival hook — so a launch-triggered campaign has a screen to match against.

Re-report when the app returns to the foreground

When the user backgrounds your app and comes back, they are on the same screen but your CEP may need the in-app re-requested. The SDK does not do this for you. Re-report the last screen on foreground:

The same pattern applies on other stacks (scenePhase on iOS, ON_START on Android, AppLifecycleListener on Flutter). Repeating the same screen name is safe.


5. Flutter with your router

DigiaNavigatorObserver works with GoRouter — pass it in observers:

What name lands depends on how you declared the route:

  • Named route (GoRoute(name: 'checkout', …)) → reports checkout. Naming your routes gives you clean dashboard names for free — this is the recommended setup.

  • Unnamed route → reports the path pattern, for example /product/:id, not the resolved /product/42. That is stable across products (good for targeting) but is not a string a campaign owner would naturally type, so align the dashboard to it or name the route.

Add the observer to MaterialApp:

It reports RouteSettings.name on push, replace, and back-navigation. Routes without a name report nothing — including showDialog and showModalBottomSheet, which is intentional: a dialog is not a screen change, and the screen stays whatever it was underneath.

If your routes are unnamed, or you want dashboard-friendly names instead of /checkout, call Digia.setCurrentScreen manually instead.

Any router that renders through a Navigator accepts a NavigatorObserver, so DigiaNavigatorObserver can be attached — but the name it sees is whatever that router puts in RouteSettings.name, which varies.

If the reported names don't match your dashboard, report manually from each screen instead (section 3). That is always available and always exact.

A tab switch is a screen change with no route push, so no observer can see it. If your app has a bottom navigation bar over an IndexedStack, you must report tab changes yourself:

Report in both initState (for the tab the app opens on) and onTap.


6. React Native with your navigator

Per-screen with useFocusEffect is the recommended setup — see section 3.

If you cannot touch every screen, a container-level listener is a fallback:

Identical to React Navigation — import useFocusEffect from expo-router instead:

Everything else, including the hook in section 3, is unchanged.

Wix's react-native-navigation has no React focus hook. Use its own lifecycle listener, registered once at startup:

Map component names to your dashboard names rather than reporting the raw component name.

Plenty of React Native apps swap screens with state rather than a router. Report the screen wherever you make that switch:

Because there is no navigator, this single effect is complete — it fires on every switch, forward or back.


7. Choosing screen names

The name you report is matched exactly and case-sensitively against the campaign's target screens. Checkout, checkout, and /checkout are three different screens, and a mismatch fails silently.

Use semantic names from a shared constants file — not route paths. Every automatic source hands you a string a campaign owner would not naturally type:

Source
What you get

GoRouter (unnamed route)

/product/:id

Navigation-Compose

product/{id}

iOS navigation observer

HomeViewController

React Navigation

whatever the route's name prop is

One constants file per app keeps developers and campaign owners on the same vocabulary:

Conventions that avoid trouble: lowercase snake_case, no leading slash, and never a trailing space — a stray space in a dashboard screen name matches on some platforms and not others.


8. Verify it's working

With verbose logging enabled, the SDK logs every screen you report — something like Current screen set: checkout. If you never see it, your call isn't running; if you see it with the wrong value, your naming is the problem.

When a campaign is dropped for the screen, the SDK logs both sides of the comparison — the current screen (shown as <unset> if you never reported one) and the campaign's target screens. That log line tells you immediately whether the fix is to report a screen, rename it, or change the campaign.

For an end-to-end check, use Live Testing to fire a screen-targeted campaign at your device, and SDK Debug Settings to inspect SDK state on-device.


9. Use it correctly

  • Report every screen the user lands on, as early as possible and on every arrival — including the first screen after launch.

  • Use a lifecycle hook that repeats: useFocusEffect, onResume, viewDidAppear — not useEffect, onCreate, or viewDidLoad.

  • Report tab switches yourself. No navigator observer can see them.

  • Keep names identical to the dashboard (exact, case-sensitive). This is the single most common reason a screen-targeted campaign doesn't appear.

  • Set the screen before campaigns trigger. A campaign dropped for the wrong screen is never retried.

  • Delete your own CEP screen-view call. setCurrentScreen already forwards it.

Last updated