Develop Shopify apps and webhooks on localhost
#

A Shopify app needs a public HTTPS URL: Shopify loads the app in the admin from it, redirects to it during OAuth, and sends webhooks to it. Expose gives your local app that URL and shows you every request Shopify makes.

1. Share your local app
#

expose share http://localhost:3000

Shopify stores your app URL and redirect URLs, so a URL that changes means updating the app configuration each time. With Expose Pro, keep it stable:

expose share http://localhost:3000 --subdomain=my-shopify-app

2. Use the URL in your app configuration
#

Set your Expose URL as the app URL, and add your OAuth callback under the allowed redirection URLs, for example https://my-shopify-app.eu-1.sharedwithexpose.com/auth/callback. You can do this in the Shopify Dev Dashboard or Partner Dashboard, or in shopify.app.toml if you use the Shopify CLI.

If you start your app with the Shopify CLI, you can pass your own tunnel instead of the default one:

shopify app dev --tunnel-url=https://my-shopify-app.eu-1.sharedwithexpose.com:3000

The port at the end is the local port the CLI should serve the app on, so share that same port with Expose.

3. Receive webhooks
#

Subscribe to webhook topics such as orders/create or app/uninstalled in your app configuration, with a path on your Expose URL.

Shopify signs each webhook with your app's client secret and sends the signature in the X-Shopify-Hmac-Sha256 header, as a base64-encoded HMAC-SHA256 of the raw request body. Compute the same value and compare the two before you trust the payload. The topic is in X-Shopify-Topic and the shop in X-Shopify-Shop-Domain.

4. Inspect and replay
#

Open http://127.0.0.1:4040 to see every request from Shopify: app loads, OAuth redirects and webhooks, with headers, body and your response. Click Replay on a webhook to send it to your app again while you work on the handler, without placing another test order.

Troubleshooting
#

  • The admin shows a blank app or a redirect error. The app URL or redirect URL in Shopify doesn't match your current Expose URL.
  • HMAC verification fails. Use the raw body and the client secret of the same app that subscribed to the webhook.
  • Shopify needs a response within a few seconds. Acknowledge the webhook with a 200 and process it in the background.