Rovenue SDK
FunnelsNative

Offline Fallback

Bundle resolved placements with the app so a first launch with no network still opens its funnel.

Two caches stand between the device and an empty screen: the last-known placement response on disk, and — for a first launch with no network and no cache — a fallback file bundled with the app. This page is the fallback file. For the disk cache, see The native path.

Export the fallback file

In the dashboard, open SDK → Offline fallback and click Download. You get rovenue-fallback.json: every active placement, resolved anonymously — empty attributes, no locale: the honest approximation of what a first-launch device with no network and no cache would get.

Whatever a placement targets rides along — a funnel, or an experiment over funnels — because the export shares resolvePlacement with the live endpoint, so both share exactly the same targeting semantics. One file and one setFallbackPlacements call keeps placements resolving offline. Funnels are the case that matters most — a first-run onboarding that cannot open offline is the whole first impression.

The file is a JSON object, not an array — placements keyed by identifier, each value exactly the data envelope a live GET /v1/placements/:identifier returns:

{
  "formatVersion": 1,
  "generatedAt": 1758300000000,
  "projectId": "proj_123",
  "placements": {
    "onboarding": {
      "placement": { "identifier": "onboarding", "revision": 7 },
      "funnel": { "...": "the resolved native funnel" },
      "experiment": null
    }
  }
}

formatVersion must be literally 1, or the SDK throws (packages/core-rs/src/librovenue.udl:266-274). Regenerate the file whenever you publish — it is a snapshot, and the SDK only reaches for it when it has nothing fresher.

Load it per platform

Load once at launch, replacing any previously-loaded set. An individual placement entry that fails to decode is skipped, not fatal, and does not count toward the returned total (packages/core-rs/src/librovenue.udl:266-274).

On Swift, from a bundled asset or a JSON string (packages/sdk-swift/Sources/Rovenue/Rovenue.swift:769-793); on Kotlin, from an Android asset or a JSON string (packages/sdk-kotlin/src/main/kotlin/dev/rovenue/sdk/Rovenue.kt:719-734); on React Native, from a JSON string via Rovenue.setFallbackPlacements (packages/sdk-rn/src/index.ts:99); on Flutter, from a JSON string via Rovenue.instance.setFallbackPlacements (packages/sdk-flutter/rovenue_flutter/lib/src/rovenue.dart:169).

When getFunnel runs it tries network first, then the disk cache, then the fallback: the resolved funnel carries servedFromFallback, true only when the bundled file answered (packages/sdk-swift/Sources/Rovenue/FunnelUI/ResolvedFunnel.swift:18-21). A/B variant selection stays deterministic from the fallback — the same subscriber plus the same experiment key draws the same variant offline as online.

A stale export means an offline device keeps resolving whatever the placement pointed to when the file was generated. Re-export whenever you publish, and whenever you start, stop, or retarget an experiment on a placement you ship offline coverage for.

On this page