Placements
Resolve a placement to a native funnel, run A/B tests, and track views — without shipping an app update.
A placement is a named location in your app — onboarding_end,
settings_upsell, feature_gate — where a funnel may appear. Your code asks
for the placement by its identifier; the dashboard decides what to show there:
which funnel, to which audience, or which A/B-test variant. Change the
funnel, retarget the audience, or start a test without shipping an update.
A placement serves a native funnel: a multi-screen onboarding-and-paywall document drawn by the SDK's native renderer. Rovenue serves the published document, the offering (products and packages), the experiment assignment, and wires up analytics and purchase attribution automatically. See Show a Funnel for the per-platform rendering walkthrough.
getFunnel returns null when the placement resolves to nothing — it was
retired, targeted to "show nothing", or the identifier is unknown. This is
deliberate: a shipped app must never crash because a placement changed
server-side. Always handle the null branch.
Fetch a placement
if let funnel = try await Rovenue.shared.getFunnel(placementId: "onboarding_end", locale: "en") {
// Host funnel.session in RovenueFunnelView — see Show a Funnel
showFunnel(funnel)
} else {
// Placement resolved to nothing — continue without a funnel
}val funnel = Rovenue.shared.getFunnel(placementId = "onboarding_end", locale = "en")
if (funnel != null) {
showFunnel(funnel) // host funnel.session in RovenueFunnelView
}import { RovenueFunnelView } from '@rovenue/react-native-sdk';
// There is deliberately no JS getFunnel — the native side resolves the
// placement itself and this view hosts the native renderer.
<RovenueFunnelView placementIdentifier="onboarding_end" onFinished={() => {}} />// Like React Native, there is no Dart getFunnel — the platform side
// resolves the placement and this widget hosts the native view.
RovenueFunnelView(placementIdentifier: 'onboarding_end')The optional locale selects which localization of the funnel document you
receive. If the requested locale isn't configured, the funnel's default
locale is served.
How a placement resolves
In the dashboard a placement is an ordered list of audience rows. The first row whose audience matches the subscriber wins:
- Funnel — that funnel is returned directly.
- A/B test — a running experiment over funnels; the SDK deterministically draws a variant (same subscriber + same experiment ⇒ same variant, every time, on every device, even offline from cache) and returns that variant's funnel.
- Nothing —
getFunnelreturnsnullfor this audience.
An "All users" row at the bottom acts as the catch-all; without one,
non-matching subscribers get null.
Tracking and attribution
- Funnel screen events (
started,advanced,completed) are emitted automatically as the subscriber moves through the funnel. Views and unique viewers appear on the placement's page in the dashboard. - Purchase attribution is automatic: the funnel carries a
presentedContextsnapshot, and the SDK attaches it to the next purchase. Revenue is credited to the placement and funnel that converted the subscriber. You never construct or send this yourself.
Offline behavior
The last successful response for each placement is cached on device. On network failure the cached response is served, and because variant selection is deterministic, a cached A/B test still yields the same variant the server would have assigned.
Relationship to offerings
A funnel references an offering; the funnel's offering is the same hydrated
shape returned by getOfferings() — pass any of its packages straight into
purchase(pkg). Placements do not replace offerings; they decide which
funnel (and therefore which offering) a given subscriber sees at a given
location.
Offline fallback file
Placements can work offline using a bundled fallback file — the resolved
configuration for every active placement. The full reference, per-platform
setup, and the servedFromFallback flag live in
Offline fallback.
Events
Funnel session events ride a durable, at-least-once queue on the device. Events survive process kills and retries automatically on network recovery. If the server returns 5xx or network fails, the event stays queued; on 2xx, it's removed. This guarantees every completion is eventually reported, even if the user finishes the funnel and immediately closes the app.