Skip to main content

User engagement patterns

requestReview() triggers the host app's store review dialog. Whether the OS actually shows it is platform-controlled — the only lever you have is when you call it. Call it at the moment the user is most satisfied.

When to call it

Good momentsAvoid
Right after completing an order/mission/goalImmediately on app launch
On the Nth return visit or Nth completionRight after an error
After a reward is receivedDuring a screen transition

Throttled call with localStorage cooldown

import { requestReview } from '@apps-in-toss/web-framework';

const REVIEW_COOLDOWN_KEY = 'review_last_requested_at';
const COOLDOWN_MS = 7 * 24 * 60 * 60 * 1000; // 7 days

async function maybeRequestReview() {
try {
const raw = localStorage.getItem(REVIEW_COOLDOWN_KEY);
const lastAt = raw ? Number(raw) : 0;
if (Date.now() - lastAt < COOLDOWN_MS) return; // still in cooldown

await requestReview();
localStorage.setItem(REVIEW_COOLDOWN_KEY, String(Date.now()));
} catch {
// non-fatal — ignore
}
}

If a request was already made within the last 7 days, this returns early. The OS enforces its own short-term deduplication on top, so this app-level guard is a belt-and-suspenders measure.

Attach to a positive event

async function onMissionComplete(completedCount: number) {
// Ask for a review on the 3rd and 10th completions
if (completedCount === 3 || completedCount === 10) {
await maybeRequestReview();
}
}

If you want "exactly once, at the first positive moment" rather than a count-based trigger, a single localStorage flag is enough:

async function onFirstRewardReceived() {
if (localStorage.getItem('review_requested')) return;
await requestReview();
localStorage.setItem('review_requested', '1');
}