SDK
App update prompts
OTA updates ship JavaScript. When you ship a whole new binary to the App Store or Play Store, AeroPush can prompt users still on an older version to install it — as a dismissible banner, or a blocking modal for critical releases.
Add the prompt
Render <AeroPushUpdatePrompt /> once, near the root of your app. It renders nothing until the server says this device should be prompted.
import AeroPush, { AeroPushBoundary, AeroPushUpdatePrompt } from 'react-native-aeropush';
AeroPush.init({ appKey: 'apk_live_…', channel: 'production' });
AeroPush.sync();
export default function App() {
return (
<AeroPushBoundary>
<YourApp />
<AeroPushUpdatePrompt />
</AeroPushBoundary>
);
}Configure it from the dashboard
Open your project → App updates. AeroPush lists the app versions your devices actually report, with a device count for each. Pick a version and choose:
- No prompt — this version is current.
- Optional — dismissible; reappears after the snooze window (24h by default).
- Forced — blocks the app until the user updates.
You also set the title, description, “What’s New” bullets and an optional banner image. Without a banner the modal simply starts at the title — the layout stays intact.
Point it at your store listing
“Update now” has to open something. At the top of the App updates panel:
- iOS App Store ID — the digits from
apps.apple.com/app/id123456789. An App Store URL cannot be derived from a bundle id, so until this is set AeroPush has nowhere to send an iOS user and stays silent rather than opening a dead end. - Android — nothing to do. The Play listing is built from the package name already on your app.
- Store update prompts enabled — the kill switch. Turn it off to silence every prompt for this app at once, without editing a single rule.
Safeguards
- Store installs only. TestFlight, sideloaded and development builds are never prompted — they have no public listing to send the user to. See testing on a device to try prompts before you ship.
- Minimum OS. Set the OS your new build requires and AeroPush will never force a device that can’t install it — that would lock the user out for good.
- Grace period. Set a “force after” date and the prompt stays dismissible until then.
- Snooze that respects a new release. A dismissed prompt waits out its snooze window, but a newer version resets it — somebody who skipped 3.0 is still told about 3.1.
- Dead ends are refused. If there’s no store URL to open, no prompt is sent at all.
- Kill switch. One toggle at the top of the App updates panel silences every prompt for the app instantly — no release, no store review.
- Fails open. If the device is offline or the check fails, nothing is shown.
Testing on a device
Because prompts only ever reach real store installs, a release build you put on a device yourself stays silent by default. Flip appUpdateTestMode on to try the real thing:
AeroPush.init({
appKey: process.env.AEROPUSH_APP_KEY!,
// Testing only — lets store-update prompts appear on a release build you
// installed directly (Xcode, `adb install`, a shared IPA/APK).
appUpdateTestMode: true,
});Then add a rule in the dashboard for the version this build reports, set it Live, and relaunch.
getInstallSourceInfo() — which JavaScript cannot influence. The moment that same binary is downloaded from the App Store or Play Store the source becomes a store source, normal rules take over, and the flag stops meaning anything. Shipping with it on is safe.A test prompt is marked TEST MODE in the UI so it can never be mistaken for the real thing, and init() logs a reminder on every launch. TestFlight is deliberately excluded — its testers are real people, and the public listing they’d be sent to is usually older than the build they’re testing.
Testing a forced prompt blocks the app by design. To get out, set the rule to cancelable (or flip the app’s prompt kill switch) in the dashboard, then relaunch.
Bring your own UI
Prefer your own design? Use the hook and render whatever you like:
import { useAppUpdate } from 'react-native-aeropush';
export function CustomPrompt() {
const { update, openStore, dismiss } = useAppUpdate();
if (!update) return null;
return (
<YourModal dismissable={update.policy !== 'forced'}>
<Text>{update.title}</Text>
<Text>{update.description}</Text>
{update.bullets.map((b) => <Text key={b}>{b}</Text>)}
<Button title="Update now" onPress={openStore} />
{update.policy !== 'forced' && <Button title="Later" onPress={dismiss} />}
</YourModal>
);
}Theming
<AeroPushUpdatePrompt theme={{ accent: '#2563eb', accentText: '#ffffff' }} />Next: the SDK API or the CLI reference.