---
title: Migrate to theme app extensions
description: Learn how to update your app to use app blocks and app embed blocks.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/migrate
  md: >-
    https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/migrate.md
---

# Migrate to theme app extensions

This guide explains how to update apps to integrate with online stores using theme app extensions.

**Caution:**

If your app integrates with a Shopify theme and you plan to submit it to the Shopify App Store, you must use [theme app extensions](https://shopify.dev/docs/apps/build/online-store/theme-app-extensions).

***

## Theme app extension benefits

Apps that integrate with online stores will traditionally modify theme code to inject assets, extract data, and extend theme functionality. Merchants are frequently required to edit theme code, which can be intimidating and error-prone. Uninstalling apps often leaves the code edits, or ghost code, behind in the theme, which can cause quality and performance issues and takes merchants off their theme upgrade paths.

For example, apps often require the following to integrate with online stores:

* Adding snippets to the `snippets` directory of a published theme, which are then added to a page by modifying Liquid layout, template, or section files.

* Injecting JavaScript into the theme, which then injects HTML into the layout of a page.

Theme app extensions don't edit theme code, which provides the following benefits:

* Reduced risk of an app introducing breaking changes to the theme

* Minimized app support debt

* Increased app adoption by offering users a cleaner experience for app integration and customization.

* Increased user retention owing to a graceful, out of the box integration experience.

Theme app extensions reduce the effort required to integrate apps in themes. You aren't required to build integration logic and installation instructions for the different themes on which the app might be installed. Instead, you can build once for all of the themes where your app is installed. Updating your app also won't require you to build theme-specific support.

Theme app extensions automatically expose your app in the theme editor, so that you can leverage the editor's visual editing capabilities without needing to replicate them in your app.

***

## When to use app blocks

Update your app to use app blocks if your current method of theme integration includes the following types of actions:

* Using the [`Asset`](https://shopify.dev/docs/api/admin-rest/latest/resources/asset) REST Admin API resource to add content to a published theme's snippets directory and render the content by modifying Liquid layout, template, or section files.

* Using the `ScriptTag` [REST Admin API](https://shopify.dev/docs/api/admin-rest/latest/resources/scripttag) or [GraphQL Admin API](https://shopify.dev/docs/api/admin-graphql/latest/queries/scripttag) resource to inject JavaScript into the theme, which then injects HTML in the page layout.

For more use cases and information about app blocks, refer to the [theme app extensions framework](https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/configuration#app-blocks-for-themes).

***

## When to use app embed blocks

Update your app to use app embed blocks if your current method of theme integration includes the following types of actions:

* Using the `ScriptTag` resource to add JavaScript that's loaded on either some or all storefront pages.

* Using the `Asset` resource to add scripts to the theme and `<script>` tags to the theme.

* Using the `Asset` resource to add Liquid to the head of the document in `theme.liquid`.

For more use cases and information about app embed blocks, refer to the [theme app extensions framework](https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/configuration#app-embed-blocks).

**Note:**

Use app blocks if you want apps to [automatically point to dynamic sources](https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/configuration#autofill). App embed blocks only have access to the Global Liquid scope for the page on which they're rendered.

***

## Update your apps

1. If you'll use app blocks, [verify](https://shopify.dev/docs/apps/build/online-store/verify-support) whether online stores that use your app have published themes that support app blocks.

   **Note:**

   Stores with published themes that don't support app blocks will need to use your legacy onboarding flow.

2. If a published theme supports app blocks, then your app should skip all POST requests made to the `Asset` and `ScriptTag` resource.

3. Complete the [Getting started with theme app extensions](https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/build) tutorial to learn how to build a theme app extension.

***

## Confirm that your app embed is active

App embed blocks are inactive until an app user turns them on in the theme editor, and your app can't activate them on the app user's behalf. If you delete a script tag before its replacement is running, then the functionality disappears until the app user activates the app embed.

Send the app user into the theme editor with your app embed activated, using a [deep link](https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/configuration#deep-linking). Then confirm the result using one of the following methods.

### Check from your app in the Shopify admin

The [App API](https://shopify.dev/docs/api/app-home/apis/authentication-and-data/app-api) reports the activation status of your app's extensions. Call `app.extensions()` from your app in the Shopify admin:

```js
const APP_EMBED_HANDLE = 'your-app-embed';


const extensions = await shopify.app.extensions();


const themeExtensions = extensions.filter(
  (extension) => extension.type === 'theme_app_extension',
);


const isActive = themeExtensions.some((extension) =>
  extension.activations.some(
    (block) => block.handle === APP_EMBED_HANDLE && block.status === 'active',
  ),
);
```

A block's `handle` is the name of its Liquid file, so replace `your-app-embed` with your app embed block's filename. A `status` of `active` means that the block is enabled on the store's published theme. A `status` of `available` means that your app ships the block but the app user hasn't enabled it.

This method requires no additional access scopes. Because it runs in the Shopify admin, you get an answer when an app user opens your app, so record the result if you need it later.

### Check from your app's backend

The App API only answers when an app user opens your app in the Shopify admin. To check activation across stores without waiting for that, read the published theme's `config/settings_data.json` file and look for your block type. This requires the `read_themes` [access scope](https://shopify.dev/docs/api/usage/access-scopes#read_themes). Refer to [Detecting app embed blocks](https://shopify.dev/docs/apps/build/online-store/theme-app-extensions/configuration#detecting-app-embed-blocks).

***

## Remove your script tags

After you've confirmed that your app embed is active on a store, delete the script tags that it replaces with the [`scriptTagDelete`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/scriptTagDelete) mutation. Running both at once causes duplicate scripts, which can double-count analytics events or render your app's UI twice.

Script tags will stop running on March 1, 2027 whether you delete them or not. Refer to [Storefront script tags](https://shopify.dev/docs/apps/build/online-store/script-tag-deprecation/storefront).

***
