Admin, installation, and OAuth performance
These guidelines apply to apps in the Shopify admin only.
Improve your app's loading performanceAnchor link to section titled "Improve your app's loading performance"
Loading performance is an important part of a merchant’s user experience when using apps in the Shopify admin. When your app is slow to load, it dissuades merchants from adopting it, increases bounce rates, and decreases overall usage.
You can also improve your app's loading experience by minimizing visual noise, such as layout shifts, and clearly indicating loading progress. As a result, merchants will perceive your app as faster and more responsive, even if the loading time doesn't change. Refer to the Polaris best practices for loading for a complete guide on designing a high-quality experience.
Measure your app's loading performanceAnchor link to section titled "Measure your app's loading performance"
Shopify relies heavily on the web-vitals package to measure your app's performance. Each time a merchant loads your app, we gather and save the web-vitals metrics in order to better understand the merchant experience. To learn more about web-vitals, you can refer to the introduction on web.dev
To measure your app's performance, we recommend adding web-vitals to your app, capturing the performance with an analytics tool, and analyzing the aggregated data from merchant visits to your app. Though measuring web-vitals on your device can be a useful tool for debugging issues, the data can differ significantly from what merchants experience when they use your app. To ensure that you provide merchants with an outstanding app experience, you should measure and monitor merchant loading experiences with your app as well.
To add web-vitals to your app, install it from npm or load the package from a CDN.
Then, you can import the core web-vitals metrics and call each function to log the resulting metrics to your own analytics service. Detailed usage information and additional diagnostic tools can be found on the web-vitals GitHub page.
Largest Contentful PaintAnchor link to section titled "Largest Contentful Paint"
Largest Contentful Paint (LCP) measures the time from when a user begins loading your page to when the largest image or block of text is displayed. It tracks how quickly your app can display its main content to merchants.
First Input DelayAnchor link to section titled "First Input Delay"
First Input Delay (FID) measures your app responsiveness to users' input. It measures the time from when a merchant interacts with your page to when your app begins processing the response to that interaction.
Cumulative Layout ShiftAnchor link to section titled "Cumulative Layout Shift"
Cumulative Layout Shift (CLS) measures your app's visual stability. Unstable user interfaces can be frustrating for merchants, especially when an element, such as a button, that they're trying to interact with moves suddenly. Cumulative Layout Shift quantifies these kinds of disruptive experiences so you can identify and remove them.
Enable optimized loading on mobile devicesAnchor link to section titled "Enable optimized loading on mobile devices"
By default, the Shopify Mobile app opens apps in an iFrame that is hosted from the Shopify admin. Each time an app is launched, the Shopify admin site must be re-loaded, adding a significant amount of time to the app's load. With optimized loading enabled, the Shopify Mobile app loads the app directly inside of a native WebView reducing the load time signficantly.
Load Shopify App Bridge from your app bundle for redirectsAnchor link to section titled "Load Shopify App Bridge from your app bundle for redirects"
Shopify offers an option to load Shopify App Bridge from Shopify CDN. However, for optimal performance, you should load App Bridge from your app bundle instead. Loading Shopify App Bridge from your app bundle increases the chance that the merchant’s browser can access this code from the cache rather than downloading it. This can make your app more performant.
For an example of loading Shopify App Bridge from the app bundle, refer to this page in the Node app template.
Optimize your OAuth flowAnchor link to section titled "Optimize your OAuth flow"
Because OAuth is the first interaction that merchants have with your app UI, you should make sure that it's a positive experience. Follow these best practices for optimizing your OAuth performance to make your app authorization process smoother, faster, and more polished.
If you have an existing OAuth flow, then you can update your embedded app OAuth flow to follow these best practices.
Shopify offers app templates that already have OAuth implemented, and API libraries that include methods that simplify the implementation process. Using these templates or libraries helps to ensure that your implementation is complete, and that your app follows our OAuth best practices that are outlined here. You can build an app using a Shopify app template by initializing an app using Shopify CLI. For more information, refer to Create an app.
If you don't want to use an app template, then you can use the same API libraries that the templates use to implement OAuth in your own app. To learn more, refer to Getting started with OAuth.
Perform a server-side redirect to your embedded appAnchor link to section titled "Perform a server-side redirect to your embedded app"
If your embedded app doesn't need to get a new OAuth token, and the app isn't being displayed in an iframe, then you should redirect the user to the embedded app URL so that they can view your app.
You should perform a server-side 3xx redirect to the embedded app URL, rather than a client-side redirect that uses Shopify App Bridge. A server-side redirect is faster, and avoids the multiple page loads that occur during an App Bridge redirect. These page loads appear as screen flicker to the merchant.
To learn when to perform this redirect, and how to build and redirect to the embedded app URL, refer to Getting started with OAuth.
Conditionally escape your embedded app iframeAnchor link to section titled "Conditionally escape your embedded app iframe"
For merchants to grant permission for your app to access sensitive data, your app needs to redirect to the OAuth grant screen:
If your app is rendered inside of an iframe, then the grant screen won't render due to
X-Frame-Options: DENY restriction on the page, so you need to escape the iframe before redirecting.
You should only attempt to escape the iframe if the iframe exists. This avoids unnecessary HTTP redirects and requests, which increase load time and can cause screen flicker. To detect the presence of an iframe, check the request query parameters for an
embedded parameter with a value of
For more information about detecting and escaping an iframe, refer to Getting started with OAuth.
Request new tokens before rendering the UI, and only when neededAnchor link to section titled "Request new tokens before rendering the UI, and only when needed"
Your app might need to request a new token for a store for the following reasons:
- Your app doesn't have a token for the shop.
- Your app uses online tokens and the token for that shop has expired.
- Your app has a token for that shop, but it was created before you rotated the app's secret.
- Your app has a token for that shop, but your app now requires scopes that differ from the scopes granted with that token.
If any of these conditions are true, then your app should request a new token by redirecting to the grant screen instead of your app UI. This avoids users having to load the app UI before being redirected to the OAuth grant screen.
If none of these conditions are true, then the app should avoid requesting new tokens. These requests increase the time the app takes to load.
For more information about this logic, and how to implement it using Shopify API libraries, refer to Getting started with OAuth.