Skip to main content

Migrating to a multi-channel app

Caution

This guide is for existing sales channel apps that were created before explicit channel connection management was available. New sales channel apps should use the channelCreate and channelUpdate APIs from the start.

When you first install a sales channel app, Shopify automatically creates a channel connection record on your behalf. This legacy behavior limits apps to a single channel connection per shop and prevents you from providing explicit connection metadata.

By migrating to explicit channel connections, you can:

  • Provide meaningful account identifiers and names for merchant visibility
  • Attach channel specifications that describe your channel's capabilities
  • Support multiple channel connections per shop in the future

The migration process updates your app's authorization flow to explicitly manage channel connections using the channelCreate and channelUpdate mutations. This approach ensures your code works correctly regardless of whether automatic channel records are being created.


  • An existing sales channel app
  • A channel specification uploaded via Shopify CLI
  • Familiarity with the GraphQL Admin API

Anchor to Step 1: Add your channel config app extensionStep 1: Add your channel config app extension

Deploy a channel config extension with at least one channel specification that describes your channel's capabilities and regional coverage.

Caution

Ensure that create_legacy_channel_on_app_install = true is set in your shopify.extension.toml. Without it, channels won't be created when merchants install your app.


Anchor to Step 2: Update your authorization flowStep 2: Update your authorization flow

Modify your app's authorization completion logic to handle both legacy automatic records and explicit channel connections.

Anchor to Query for existing channel recordsQuery for existing channel records

After a successful authorization, query channels to check if an automatic channel record exists:

channels query

query {
channels(first: 10) {
edges {
node {
id
handle
specificationHandle
}
}
}
}

Automatic channel records lack explicit fields such as specificationHandle.

Anchor to Update or create the channel connectionUpdate or create the channel connection

Convert automatic records to an explicit connection by calling channelUpdate:

channelUpdate mutation

mutation ChannelUpdate($id: ID!, $input: ChannelUpdateInput!) {
channelUpdate(id: $id, input: $input) {
channel {
id
handle
}
}
}

Provide the following input fields:

Important channelUpdate input fields
FieldDescription
accountIdThe unique identifier for the merchant's account on your platform.
accountNameA human-readable name for the merchant's account.
specificationHandleThe handle of one of your uploaded channel specifications.

If no record exists, call channelCreate to establish a new explicit connection:

channelCreate mutation

mutation ChannelCreate($input: ChannelCreateInput!) {
channelCreate(input: $input) {
channel {
id
handle
}
userErrors {
field
message
}
}
}
Tip

This branching logic makes your authorization code resilient to both legacy and modern states. The same code path works before and after you disable automatic channel creation.


Anchor to Step 3: Disable automatic channel creationStep 3: Disable automatic channel creation

Once your updated authorization flow is deployed and you've verified it works correctly, disable the legacy automatic channel creation behavior.

In your shopify.extension.toml, remove create_legacy_channel_on_app_install = true.

Then redeploy your app:

shopify app deploy

After deployment, Shopify will no longer create automatic channel records when merchants install your app.

Note

Unless or until you upgrade all legacy merchants, you should keep the authorization code that uses channelUpdate.


Anchor to Step 4: Clean up existing legacy recordsStep 4: Clean up existing legacy records

After disabling automatic channel creation, some merchants will still have legacy automatic records if they haven't re-authorized with your app. You can clean these up with a batch process using the following options:

  1. Convert legacy records. Query for shops with automatic records and call channelUpdate to convert them to explicit connections.
  2. Remove stale records. If a channel connection is no longer valid, delete the legacy record:

channelDelete mutation

mutation ChannelDelete($id: ID!) {
channelDelete(id: $id) {
deletedId
userErrors {
field
message
}
}
}

Anchor to Step 5: (Optional) Add multiple connection supportStep 5: (Optional) Add multiple connection support

With explicit channel management in place, you can extend your app to support multiple channel connections per shop. Use channelCreate to establish additional connections as needed by your platform.

Learn more about managing multiple channel connections.


Was this page helpful?