Redirect to the plan selection page
A common pattern is to redirect merchants to your plan selection page after they install your app. However, because embedded apps are rendered in the Shopify admin inside an iframe, they don't have permission to manipulate the parent browser window, including redirects.
Shopify's React Router package provides utilities that enable apps to redirect elsewhere in the Shopify admin. This keeps the user experience smooth while working within iframe constraints.
Anchor to RequirementsRequirements
- An embedded app scaffolded with React Router. This includes the @shopify/shopify-app-react-router package by default.
- Your app needs to have Shopify App Pricing enabled, with at least one plan configured.
- A Partner API client with the Manage apps permission. The Active Subscription API requires this permission, and it supports only public apps.
Anchor to Check subscription status in React RouterCheck subscription status in React Router
The example in this section runs in the loader for the app's root route, so it works no matter which app route the user arrives at. It does the following:
- Queries the Active Subscription API on the Partner API to check whether the shop has an active Shopify App Pricing subscription. With Shopify App Pricing, subscription status comes from the Partner API, not from the GraphQL Admin API.
- If not, then redirects to the plan selection page with the redirect utility from
@shopify/shopify-app-react-router, which can navigate outside the app frame. - If there is an active subscription, then renders your app's content normally.
The example reads the following values:
YOUR_APP_HANDLE: Thehandlefrom yourshopify.app.tomlfile. The store handle comes from the session's shop domain (for example,cool-shopfromcool-shop.myshopify.com).SHOPIFY_PARTNER_ORG_ID: Your organization ID, which appears in your Partner Dashboard URL.SHOPIFY_PARTNER_API_ACCESS_TOKEN: The access token for your Partner API client. Refer to Partner API authentication.SHOPIFY_APP_GID: Your app's GID in the formgid://shopify/App/{app_id}, where{app_id}is the numeric ID in your app's Partner Dashboard URL.
activeSubscription requires the shop's GID rather than its myshopify.com domain, so the example queries shop { id } through the GraphQL Admin API. The Partner API has a rate limit of four requests per second for each client, so the example throws on throttled or failed responses instead of treating them as a missing subscription. In production, cache only a confirmed subscription for each shop, with a short expiry such as five minutes. A merchant who just approved a plan is then checked immediately, and a cancellation or freeze is picked up when the cached entry expires.
The route file handles the check and redirect. The Partner API request lives in its own server module so that other routes can reuse it.
app/routes/app.jsx
app/partner-api.server.js
If your app migrated from the Billing API, then existing Billing API subscriptions aren't returned by activeSubscription until you migrate them to Shopify App Pricing. Until then, also check billing.check() before redirecting. It queries currentAppInstallation and returns hasActivePayment: true for both active Billing API subscriptions and active one-time purchases. Remove that call after you've migrated your subscriptions and no existing one-time purchases still grant access.
If your app migrated from the Billing API, then existing Billing API subscriptions aren't returned by activeSubscription until you migrate them to Shopify App Pricing. Until then, also check billing.check() before redirecting. It queries currentAppInstallation and returns hasActivePayment: true for both active Billing API subscriptions and active one-time purchases. Remove that call after you've migrated your subscriptions and no existing one-time purchases still grant access.
Anchor to Next stepsNext steps
- Learn more about Shopify App Pricing.
- Query subscription data with the Active Subscription API.