A common pattern is to redirect merchants to your [plan selection page](/docs/apps/launch/billing/managed-pricing#plan-selection-page) after they install your app. However, because [embedded apps](/docs/apps/build/admin) are rendered in the Shopify admin inside an iframe, they don’t have permission to manipulate the parent browser window, including redirects. Shopify's Remix package](/docs/api/shopify-app-remix) provides utilities that allow apps to redirect elsewhere in the Shopify admin. This ensures a smoother, more seamless user experience while working within iframe constraints. ## Requirements - An embedded app [scaffolded with Remix](/docs/apps/build/scaffold-app). This includes the [@shopify/shopify-app-remix](/docs/api/shopify-app-remix) package by default. - Your app needs to have [Managed Pricing enabled](/docs/apps/launch/billing/managed-pricing#opt-in-to-managed-pricing), with at least one plan configured. ## Check subscription status in Remix The example code in this section demonstrates the basic steps required to implement this behavior in a Remix app: 1. Check if the logged-in user has an active app subscription. 1. If not, then redirect to the plan selection page. 1. If there is an active subscription, then render your app’s content normally. The [@shopify/shopify-app-remix](/docs/api/shopify-app-remix) package includes built-in utilities for handling [billing queries](/docs/api/shopify-app-remix/apis/billing#example-check) and [redirects](/docs/api/shopify-app-remix/authenticate/admin#example-redirect). You can use these utilities in your [Remix loaders](https://remix.run/docs/en/main/route/loader) to check the user’s plan subscription status and redirect if needed. In this example, the subscription plan check runs at the app’s root route, so it works no matter which app route the user arrives at. The redirect uses a `shopify://` deep link instead of a standard URL. This delegates routing to Shopify, which makes the redirect more resilient to future URL changes in the Shopify admin. ```js // app/routes/app.jsx export const loader = async ({ request }) => { // Replace with the "app_handle" from your shopify.app.toml file const appHandle = "YOUR_APP_HANDLE"; // Authenticate with Shopify credentials to handle server-side queries const { authenticate } = await import("../shopify.server"); // Initiate billing and redirect utilities const { billing, redirect } = await authenticate.admin(request); // Check whether the store has an active subscription const { hasActivePayment } = await billing.check(); // If there's no active subscription, redirect to the plan selection page... if (!hasActivePayment) { return redirect(`shopify://admin/charges/${appHandle}/pricing_plans`, { target: "_top", // required since the URL is outside the embedded app scope }); } // ...Otherwise, continue loading the app as normal return { apiKey: process.env.SHOPIFY_API_KEY || "", }; }; ``` ## Next Steps - Learn more about [Managed Pricing](/docs/apps/launch/billing/managed-pricing)