Skip to main content

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 Remix package 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.



Anchor to Check subscription status in RemixCheck 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.
  2. If not, then redirect to the plan selection page.
  3. If there is an active subscription, then render your app’s content normally.

The @shopify/shopify-app-remix package includes built-in utilities for handling billing queries and redirects. You can use these utilities in your Remix loaders 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 the web URL for the plan selection page, which requires both the store handle and your app handle. The store handle is dynamic and should be extracted from the shop domain (for example, "cool-shop" from "cool-shop.myshopify.com"). The app handle is defined in your shopify.app.toml file.

// 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, session } = await authenticate.admin(request);
// Check whether the store has an active subscription
const { hasActivePayment } = await billing.check();

// Extract the store handle from the shop domain
// e.g., "cool-shop" from "cool-shop.myshopify.com"
const shop = session.shop; // e.g., "cool-shop.myshopify.com"
const storeHandle = shop.replace('.myshopify.com', '');

// If there's no active subscription, redirect to the plan selection page...
if (!hasActivePayment) {
return redirect(`https://admin.shopify.com/store/${storeHandle}/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 || "",
};
};


Was this page helpful?