Offline and Fallback
How bundled fallback solves the cold-start problem, the seed → cache → network resolution chain, and how to package seeds per platform.
The cold-start problem
SDKs cache bundles on device after the first successful fetch, so a returning user offline still sees real strings. But a cold start with no network has nothing cached: a first launch on a plane, an SSG/SSR build on a machine with no network access, a CI run. Without help, the SDK degrades to showing key names.
Bundled fallback closes that gap: you commit published bundles into your app's repo and ship them inside the app. At startup the SDK seeds from them: real, verified strings on the very first frame, network or not.
The resolution chain
For each locale, the SDK resolves strings from three sources:
- Bundled seed: the bundles shipped inside the app, in the seed directory
airstrings/bundles/. - Local cache: bundles persisted from earlier fetches.
- Network: a background refresh that fetches the latest published bundle.
Every candidate is verified: a seed file sits in a repo anyone with commit access can touch, so it gets the exact same signature verification as a network bundle. Among verified candidates, the highest revision wins:
- A seed never overrides a newer verified bundle already in the cache. Shipping an app update with an older seed than what the device has cached is simply a no-op.
- If the seed wins, it is saved into the cache, so later cold starts don't depend on the seed still being readable.
- The background network refresh obeys the same rule: a fetched bundle only applies if its revision is higher.
A corrupt or tampered seed file is rejected loudly (a hard error on the SDK's error channel, and startup continues without it). A missing seed is not an error at all: the SDK silently falls back to cache, then network.
Creating the seed: airstrings bundles pull
airstrings bundles pullThis downloads the published, signed bundles for the active environment into airstrings/bundles/ at your workspace root, verifying every signature before writing, plus a manifest.json provenance record (which environment and revisions the pull came from, advisory only). Running it twice with no upstream changes produces zero diff.
Commit the folder:
git add airstrings/bundles
git commit -m "chore: update bundled fallback strings"The folder contains public keys and localized strings only (never credentials or private key material), so it is safe to commit and safe to review like any other diff.
One seed directory holds bundles for exactly one environment. If you build multiple flavors against different environments, pull into a distinct directory per flavor.
Note this is not the same command as airstrings pull, which fetches draft workspace strings as editable CSVs. bundles pull fetches published, signed bundles: immutable delivery artifacts. See CLI publishing.
Tip: run airstrings bundles pull in CI or as a pre-release step. A fresh install serves the committed seed until its first successful fetch, so keeping the snapshot current keeps first launches current.
Packaging per platform
The relative path airstrings/bundles/ is the same everywhere; only where it lives in your build differs.
| Platform | Where the seed lives | Setup |
|---|---|---|
| Web (Node, SSG/SSR) | airstrings/bundles/ in the working directory | None, detected automatically |
| Web (browser) | Build output | Import the bundle JSON at build time and pass it via the seed option |
| iOS | App bundle, under airstrings/bundles/ | Add the committed folder as a folder reference in Xcode, or a .copy resource in SPM |
| Android | assets/airstrings/bundles/ | Copy the folder into src/main/assets/, or map it as an assets source directory |
Seeding is automatic when the directory is present; each SDK lets you override the location or disable it. See your SDK's guide for the exact wiring: iOS, Android, Web.
Bundles, Signing, and the CDN
What a bundle is, what happens when you publish, why every bundle is signed, and how key rotation works.
String Variants
A/B test string values by attaching an experiment to a key: deterministic, stateless, cross-platform selection driven by an assignment id, with exposure events you forward to your own analytics.