Create an Events subscription
Suppose you're building an app that keeps a merchant's external product catalog in sync with Shopify. The external catalog already exists. Your app's job is to reflect changes as they happen.
When a product is created in Shopify, your app needs to add it to the external catalog. When it's deleted, your app needs to remove it. When a variant's price or compare-at price changes, your app needs to patch the corresponding record. In this tutorial, you'll set up Events subscriptions for all three actions.
Events is in developer preview on the unstable API version, available today for a subset of topics. Use it for early testing ahead of a stable release and broader topic coverage. For topics not yet supported, use webhooks alongside Events in the same shopify.app.toml. As Events expands topic coverage, it will become the primary subscription mechanism.
Events is in developer preview on the unstable API version, available today for a subset of topics. Use it for early testing ahead of a stable release and broader topic coverage. For topics not yet supported, use webhooks alongside Events in the same shopify.app.toml. As Events expands topic coverage, it will become the primary subscription mechanism.
Anchor to What you'll learnWhat you'll learn
In this tutorial, you'll learn how to do the following tasks:
- Write Events subscriptions for create, delete, and update actions.
- Use
triggersand a customqueryto receive only the data you need. - Handle deliveries in route handlers, and use
fields_changedandquery_variablesto process those deliveries.
Requirements
Events require Shopify CLI version 3.92 or higher. Run shopify version to check, and see upgrade instructions if needed.
Scaffold an app that uses the React Router template.
Project
Anchor to Subscribe to product EventsSubscribe to product Events
Configure subscriptions in shopify.app.toml, define a route to receive deliveries, and process the payload in your handler. You'll start with create and delete, then add an update subscription that narrows what's delivered with triggers, query, and query_filter.
Anchor to Configure top-level propertiesConfigure top-level properties
Before you add subscriptions, set the access scope your topic requires and pin the Events API version.
Anchor to Update your access scopesUpdate your access scopes
Events topics require scopes.
Because you're subscribing to Product topic changes, include the read_products scope in the configuration file.
Anchor to Set the versionSet the version
Add an [events] block and pin api_version to unstable. Events is only available on the unstable API version while it's in developer preview.
Anchor to Subscribe to product creates and deletesSubscribe to product creates and deletes
Create subscriptions for create and delete actions on the Product topic, then define a single route handler that receives both.
The handler uses authenticate.webhook to verify the request and read shop, topic, and payload from the delivery.
Anchor to Configure a ,[object Object], subscriptionConfigure a create subscription
create subscriptionAdd an [[events.subscription]] block.
The handle identifies which subscription triggered a delivery.
Set topic to the resource name, actions to the operations to listen for, and uri to the route that will receive deliveries.
Anchor to Configure a ,[object Object], subscriptionConfigure a delete subscription
delete subscriptionAdd a second [[events.subscription]] block for the Product topic with actions = ["delete"] using the same route.
Anchor to Define a routeDefine a route
Use authenticate.webhook from your app's shopify.server module.
Shopify's library validates the request and gives you shop, topic, and payload.
Log one short line and the full payload so you can inspect it in the terminal where shopify app dev is running.
All subscriptions in this tutorial will reuse this same endpoint.
If you're not using the React Router template, you'll need to verify HMAC signatures yourself. See Verify Events deliveries for the raw verification approach.
Anchor to Subscribe to product updatesSubscribe to product updates
Create another subscription to receive updates for specific field changes, not just create and delete actions.
You'll add triggers to narrow deliveries to variant price and compare-at price changes, a query to fetch exactly the data your sync needs, and a query_filter to suppress deliveries for inactive products.
Anchor to Define the subscriptionDefine the subscription
Add a new [[events.subscription]] block for the Product topic with actions = ["update"].
Anchor to Add triggersAdd triggers
Add triggers to narrow deliveries to variant-level changes your sync logic actually needs.
Without triggers, every update to the product fires a delivery.
Anchor to Add a queryAdd a query
Add a query to shape the payload.
When a trigger fires, Shopify executes this query and includes the result in the data field of the delivery.
Without a query, the delivery has no data field.
Anchor to Add a query filterAdd a query filter
Add query_filter to suppress deliveries for products that shouldn't be synced to the external catalog.
The filter evaluates after the query runs, so you can filter on any field returned by your query.
Anchor to Process update deliveriesProcess update deliveries
Update deliveries with a configured query include fields_changed, query_variables, and data.
Each field serves a different purpose in your handler.
Anchor to Read ,[object Object], to identify what triggered the deliveryRead fields_changed to identify what triggered the delivery
fields_changed to identify what triggered the deliveryfields_changed is an array of field paths, each embedding the GID of the entity that changed.
Use it to know which specific field and variant caused this delivery.
Anchor to Use ,[object Object], to access entity IDsUse query_variables to access entity IDs
query_variables to access entity IDsquery_variables gives you the entity IDs directly.
No need to parse them from the query response or from fields_changed paths.
Anchor to Act on the query dataAct on the query data
The data field contains the response from your subscription's query.
Use it to access the fields your app needs without making a follow-up API call.
Queries executed by subscriptions don't count toward your rate limits but have a 250 point complexity limit.
Queries executed by subscriptions don't count toward your rate limits but have a 250 point complexity limit.
Anchor to Test your subscriptionsTest your subscriptions
Run your app on a dev store and confirm each subscription delivers as expected.
Anchor to Set up testing on a dev storeSet up testing on a dev store
Save your TOML file and run shopify app dev. If app dev is already running, the subscription is automatically created or updated.
Anchor to Confirm ,[object Object], and ,[object Object], behaviorConfirm create and delete behavior
create and delete behaviorNavigate to your test shop and create a new product. The payload should print to your CLI.
Delete a product. Your delete endpoint should receive a delivery.
Anchor to Confirm ,[object Object], behaviorConfirm update behavior
update behaviorChange the price of a product variant on an active product. The payload should print to your CLI, including fields_changed, query_variables, and data.
Update the price on an inactive product, or update the title on an active product. In both cases, you don't receive a delivery.
Anchor to Deploy your appDeploy your app
When you're ready to release your subscriptions to production, navigate to your app directory and run the following command:
Terminal
Optionally, you can provide a name or message for the version using the --version and --message flags.
Releasing an app version replaces the current active version that's served to stores that have your app installed. It might take several minutes for app users to be upgraded to the new version.
If you want to create a version, but avoid releasing it to users, then run the deploy command with a --no-release flag.
You can release the unreleased app version using Shopify CLI's release command, or through the Dev Dashboard.
If you want to create a version, but avoid releasing it to users, then run the deploy command with a --no-release flag.
You can release the unreleased app version using Shopify CLI's release command, or through the Dev Dashboard.