Supported on: iOS SDK
1.0.70+ · Android SDK 1.0.42+ · React Native SDK 1.0.7+ (New Architecture only)Overview
Server-driven screens let growth teams design and deploy native screens from the AppDNA Console without an app release. Screens are composed from the same content-block and section library used by paywalls, onboarding, in-app messages, and surveys, then delivered to the SDK via the remote config bundle. On React Native, screens are rendered fully natively — SwiftUI on iOS and Jetpack Compose on Android — so the experience matches a hand-built native UI. Use screens to ship feature announcements, upgrade prompts, referral surfaces, guided tutorials, and other composable native surfaces from the Console.Show a Screen
show(...) resolves a boolean: whether the screen was presented. It does not resolve the
outcome, and it cannot: a screen can be dismissed minutes after it appears. What the user did arrives
on onScreenDismissed on the delegate you register with setDelegate(...) — see
Screen Delegate below.
Show a Multi-Screen Flow
showFlow(...) likewise resolves whether the flow was presented. The result — completion, the screens
viewed, the responses — arrives on the delegate’s onFlowCompleted.
Dismiss
<AppDNAScreenSlot> — inline screens
show(...) and showFlow(...) present a screen over your app. A slot embeds one inside your
own layout: you place <AppDNAScreenSlot name="..."> in your React tree, the Console assigns a screen
to that slot name, and the native renderer draws it in place. It is the only React component the
package exports.
- An empty slot renders nothing — no visual impact and no reserved space once measured.
- Content updates on the next config refresh.
- Audience targeting applies per slot.
- The slot raises no delegate callbacks:
onScreenPresented/onScreenDismissed/onFlowCompletedbelong toshow(...)/showFlow(...). A slot is content, not a presentation.
Navigation Interception
Inject screens automatically between app navigations:AppDNAScreenDelegate on every navigation event so you can route or suppress as needed. Pass an array of route names to limit interception to an allowlist — exact names and trailing * wildcards.
Debug Preview
Render a screen from raw JSON for design or QA preview without publishing to the Console:preview takes the screen config as a JSON string, not an object:
Module Access
Access the screen module through theAppDNA.screens namespace:
Audience-Based Presentation
In addition to imperativeshow(...) calls, screens can be presented automatically by Console-driven audience targeting:
- Design the screen in the AppDNA Console.
- Attach a trigger (event-based, schedule-based, or app-state-based) and an audience.
- Publish the screen.
- Call
AppDNA.configure(...)at app startup. - Identify the user with
AppDNA.identify(...)so targeting rules can resolve. - Track relevant events with
AppDNA.track(...)so event triggers can fire.
Screen Delegate
AppDNAScreenDelegate exposes the four screen lifecycle methods. The delegate is implemented as an object literal or class and registered with the module:
Pass
null to clear a delegate. Registering a new delegate
replaces the previous one, and AppDNA.shutdown() detaches everything. Register once at app
startup rather than from a component that mounts and unmounts.Delegate Method Reference
Result and action payloads are delivered as
Record<string, unknown> rather than typed classes. This keeps the bridge forward-compatible with new fields the native SDKs add (for example, additions like last_action or duration_ms) without requiring a React Native package bump.
Sections and Content Blocks
Screens are composed of an ordered list of sections. Each section pulls from the unified registry shared across all SDK modules, so the same content blocks you use in paywalls, onboarding, in-app messages, and surveys are available inside screens:
Sections are assembled in the Console and stream to the SDK through the config bundle. The React Native SDK does not need to know which sections a screen contains — the native renderer reads the configuration and lays the screen out.
Presentation Modes
Screens support several presentation modes configured per screen in the Console. The native renderer honors each mode on the appropriate platform:
Unrecognized values fall through to
fullscreen on Android. The React Native SDK does not need to pick a mode — the Console controls the presentation per screen.
Auto-Tracked Events
The native SDKs emit standard analytics events for every screen interaction. These events flow through the same event pipeline as other AppDNA events:
You do not need to forward or duplicate these events from TypeScript — the native SDK already emits them.
Configuration in Console
Each screen is configured in the AppDNA Console with:- Screen ID — the canonical identifier used by audience triggers and analytics events.
- Layout — scroll, stack, or grid container that wraps the section list.
- Sections — an ordered list pulled from the unified section registry.
- Presentation —
fullscreen,modal,bottom_sheet, orpush. - Trigger — event-based (
event_namematching), schedule-based (cron-style), or app-state-based. - Audience — targeting rules across user traits, device info, remote config, computed values, and experiment exposures.
- Style — per-screen theme, typography overrides, brand colors, and animation defaults.
Full Example
Screens are delivered via the same Firestore-backed config bundle as other SDK modules. Ensure your app has network access on first launch to fetch the latest screen configurations. After the first successful fetch, the native SDKs cache the bundle and continue rendering screens offline.

