onebox

Guide 17 of 30

For your agent: .md · all guides

On this page
  1. What it costs
  2. Apple’s rules
  3. Steps
  4. Where the values go
  5. Check it works
  6. Common errors

Ask for a rating

Runs on: your Mac (the app).

Ratings help people trust the app, and they help it in search. iOS has one system prompt for this. It shows the stars and an optional review, without leaving the app. Apple decides when the prompt really shows. This guide adds it at a good moment, within Apple’s rules, plus a “Rate the app” row for the settings screen.

What it costs

Nothing. The Expo package is expo-store-review. It has native code, so it needs a new build. Ship it with a release, not as an EAS Update.

Apple’s rules

Checked on 2026-10-01 against Apple’s StoreKit documentation (https://developer.apple.com/documentation/storekit/requesting-app-store-reviews) and the App Review Guidelines.

Steps

1. Install the package

From the Expo app folder:

npx expo install expo-store-review

Then make a new development build (expo-app.md, step 5).

2. Pick a success moment

Ask right after the user got what they came for: they saved their third recipe, finished a workout, or shared a result. The moment is yours to pick. Apple only limits how often the prompt shows.

Do not ask:

3. Ask once the moment comes

Count the successes, and ask after a few of them. AsyncStorage is fine for this counter: it is not a secret (expo-app.md, step 9).

// src/review/askForReview.ts
import AsyncStorage from "@react-native-async-storage/async-storage";
import * as StoreReview from "expo-store-review";

const KEY = "review.successCount";
const ASK_AT = [3, 10, 30];   // iOS shows it at most 3 times a year anyway

// Call after a success, once the success screen shows.
export async function onSuccess() {
  const n = Number((await AsyncStorage.getItem(KEY)) ?? "0") + 1;
  await AsyncStorage.setItem(KEY, String(n));
  if (!ASK_AT.includes(n)) return;
  if (await StoreReview.isAvailableAsync()) await StoreReview.requestReview();
}

Then call it where the success happens:

await saveRecipe(recipe);
showSaved();
void onSuccess();

isAvailableAsync() returns false in TestFlight. requestReview() returns nothing, whether the prompt showed or not.

4. A “Rate the app” row in settings

A row the user taps on purpose is fine. It opens the App Store page, where the user can write a review:

import { Linking } from "react-native";

// The app's Apple ID: ascAppId in eas.json. It is not a secret.
const APP_STORE_ID = "1234567890";

export const openWriteReview = () =>
  Linking.openURL(`https://apps.apple.com/app/id${APP_STORE_ID}?action=write-review`);

This link is Apple’s own. It works only after the app is live in the store.

Where the values go

ValueWhere
The App Store IDsubmit.production.ios.ascAppId in eas.json; copy it into the code or the app config
The success counterAsyncStorage on the phone

Check it works

Common errors

Wrong or out of date? Fix it on GitHub.