A developer tutorial application demonstrating how to integrate Shopify webhooks, the Hookdeck Event Gateway, and Ably to display real-time purchase notifications in a Shopify online store with festive animations.
This is an example/tutorial app that shows developers how to:
- Receive Shopify order webhooks reliably through the Hookdeck Event Gateway
- Process webhook events in a Remix-based Shopify app
- Forward events to Ably for real-time pub/sub messaging
- Display live notifications in a Shopify storefront using theme app extensions
- Create interactive UI elements with holiday-themed animations
Note: This is a demonstration app for learning purposes, not a production-ready application for merchants to install.
The application uses two Hookdeck Event Gateway connections for reliable webhook processing and real-time delivery:
Connection 1: Shopify → Event Gateway → App
- Receives Shopify webhooks reliably
- Queues and delivers to app with retries
Connection 2: App → Event Gateway Publish API → Ably
- Publishes PII-free notifications to Event Gateway
- Event Gateway forwards to Ably for real-time broadcast
sequenceDiagram
participant Shopify
participant EventGateway as Hookdeck Event Gateway
participant App as Remix App<br/>(webhooks.orders.create.tsx)
participant Ably
participant Storefront as Storefront Extension<br/>(notifications.js)
Note over Shopify: 1. Order Created
Shopify->>EventGateway: 2. POST /webhooks (orders/create)
Note over EventGateway: 3. Receives & queues webhook<br/>at Source (Connection 1)
EventGateway->>App: 4. Delivers webhook with retries
Note over App: 5. Extracts order data
App->>App: 6. Transform to PII-free notification
Note over App: 7. Removes customer PII<br/>Fetches product images
App->>EventGateway: 8. POST to Publish API<br/>(shopify-notifications-publish)
Note over EventGateway: 9. Queues event<br/>(Connection 2)
EventGateway->>Ably: 10. Forwards to Ably REST API
Note over Ably: 11. Broadcasts to channel
Ably->>Storefront: 12. Real-time notification
Note over Storefront: 13. Displays notification<br/>with snowflake animation
1. Order Created in Shopify
↓
2. Shopify triggers orders/create webhook
↓
3. Event Gateway receives and queues the webhook at the Source
↓
4. Event Gateway delivers webhook to app webhook handler
(app/routes/webhooks.orders.create.tsx)
↓
5. App transforms order to PII-free notification and publishes to Event Gateway
(app/helpers/hookdeck-publisher.ts)
↓
6. Event Gateway queues and forwards event to Ably via REST API
↓
7. Ably broadcasts to all connected clients
↓
8. Storefront receives event via Ably Realtime
(extensions/live-notifications/assets/notifications.js)
↓
9. Notification displayed with snowflake animation
(extensions/live-notifications/blocks/notifications.liquid)
This project contains both a Shopify app and a theme app extension:
- Shopify App: The backend Remix application that handles webhooks, manages data, and provides an admin interface. It runs on a server and integrates with Shopify's Admin API.
- Theme App Extension: Frontend components that appear in the merchant's online store. Extensions add blocks, sections, or functionality directly to the storefront without modifying theme code.
app/routes/webhooks.orders.create.tsx- Webhook endpoint that receives order creation events from Shopify via the Event Gateway and publishes PII-free notificationsapp/helpers/hookdeck-publisher.ts- Helper functions for publishing events to the Event Gateway, including:- Transforming orders to PII-free notifications (removes customer data)
- Fetching product images from Shopify
- Publishing to the Event Gateway's Publish API with shop-specific routing
scripts/setup-hookdeck.ts- Automated setup script that creates both Event Gateway connections
extensions/live-notifications/blocks/notifications.liquid- Theme app extension block with festive holiday lights and snowfall animationsextensions/live-notifications/assets/notifications.js- Client-side JavaScript that:- Connects to Ably Realtime
- Subscribes to notification events
- Creates snowflake animations
- Handles interactive elements (clickable lights and snowflakes)
extensions/live-notifications/src/notifications.scss- Source SCSS styles (compiled tonotifications.css)extensions/live-notifications/assets/notifications.css- Compiled CSS (generated from SCSS, not manually edited)
shopify.app.toml- Shopify app configuration including:- Webhook subscriptions for
orders/create - Required OAuth scopes (
read_products,read_orders) - App authentication settings
- Webhook subscriptions for
package.json- Dependencies including:@shopify/shopify-app-remix- Shopify app framework- Ably client library (loaded via CDN in storefront)
Before setting up this app, you'll need:
- Node.js (v18.20+, v20.10+, or v21.0.0+)
- Shopify Partner Account - Create one here
- Shopify Development Store - Create from your Partner Dashboard
- Hookdeck Account - Sign up at hookdeck.com for the Event Gateway
- Hookdeck CLI - Install globally with
npm install -g @hookdeck/cli - Ably Account - Sign up at ably.com
- Log in to your Hookdeck Dashboard
- Navigate to Settings → API Keys
- Create or copy your API key
You'll need two separate Ably API keys with different permissions:
1. Publishing API Key (used in Event Gateway)
This key is used by the Event Gateway to forward events to Ably and must have publish permissions only.
- Log in to your Ably Dashboard
- Navigate to your app → API Keys
- Click "Create new API key"
- Name it "Event Gateway Publisher"
- Under Capabilities, select only "Publish"
- Copy the full API key (format:
appId.keyId:keySecret) - Save this key - you'll use it in your
.envfile
2. Subscribe API Key (for Storefront)
This key is used by the storefront extension to receive notifications and must have subscribe permissions only.
- In the Ably Dashboard, create another API key
- Name it "Storefront Subscriber"
- Under Capabilities, select only "Subscribe"
- Copy this API key
- Save this key - you'll use it in the extension JavaScript file
Learn more about Ably API key permissions.
The Shopify CLI will automatically configure your app when you run npm run dev for the first time:
- The CLI prompts you to create a new app or select an existing one
- The
SHOPIFY_API_KEY(client_id) is automatically saved toshopify.app.toml - You need to manually add
SHOPIFY_API_SECRETto your.envfile
To get your SHOPIFY_API_SECRET:
- Go to your Shopify Partner Dashboard
- Navigate to Apps → [Your App]
- Go to the Configuration tab
- Copy the "Client secret" value
- Add it to your
.envfile asSHOPIFY_API_SECRET
This secret is required for webhook signature verification by the Event Gateway.
Create a .env file in the root directory with the following variables:
# Shopify App Credentials
SHOPIFY_API_KEY=
SHOPIFY_API_SECRET=
# Hookdeck Configuration
HOOKDECK_API_KEY=
# Ably Configuration (use the publishing key)
ABLY_API_KEY=git clone https://github.com/hookdeck/shopify-festive-notifications.git
cd shopify-festive-notifications
npm installEdit extensions/live-notifications/assets/notifications.js and replace the placeholder API key with your Ably Subscribe API key:
const ably = new Ably.Realtime("YOUR_ABLY_SUBSCRIBE_API_KEY");Important: Use the subscribe-only API key here, not the publishing key from your .env file.
Note: In production, this should be handled more securely using token authentication.
The Hookdeck CLI is required for this demo application to receive webhooks locally.
-
Install Hookdeck CLI globally:
npm install -g @hookdeck/cli
-
Login to Hookdeck:
hookdeck login
This authenticates the CLI with your Hookdeck account.
npm run devThis will:
- Create a tunnel for local development (using Cloudflare)
- Prompt you to create/select a Shopify app
- Install the app on your development store
- Start the development server
Note on Tunneling:
- The Cloudflare tunnel created by
npm run devis required for Shopify to communicate with your local app (OAuth, app embeds, admin interface) - The Hookdeck CLI is used to receive webhooks locally and provides better debugging capabilities
- Both run simultaneously: Cloudflare tunnel for the app, Hookdeck CLI for webhooks
Benefits of Hookdeck CLI for webhooks:
- Real-time webhook inspection and debugging
- Replay webhooks during development
- Test different payloads easily
- View webhook history and errors
- No need to trigger real Shopify events repeatedly
Run the automated setup script to create both Event Gateway connections:
npm run setup:hookdeckThis script automatically creates:
-
Connection 1: Shopify → App
- Source:
shopify-webhooks(for receiving webhooks from Shopify) - Destination: Points to your app's webhook handler
- CLI Connection: For local development
- Webhook Signing: Automatically configured using your
SHOPIFY_API_SECRETto verify webhook authenticity
- Source:
-
Connection 2: App → Ably
- Source:
shopify-notifications-publish(for publishing from your app) - Destination:
ably-rest-api(forwards to Ably REST API) - Authentication: Uses your Ably publishing API key from
.env - Routing: Shop-specific channels for multi-tenant support
- Source:
The script uses your ABLY_API_KEY and SHOPIFY_API_SECRET from .env to configure connections automatically.
Note: For production deployments, you'll need to update the destination URL in Connection 1 to point to your production server instead of localhost.
In a second terminal, start the Hookdeck CLI to forward webhooks to your local server:
npm run hookdeck:listenNote
This runs the command:
hookdeck listen 3000 shopify-webhooksThis creates or reuses an Event Gateway Connection that forwards events from a shopify-webhooks Source to localhost:3000. Keep this terminal running.
- Go to your Shopify admin → Online Store → Themes
- Click "Customize" on your active theme
- Navigate to any page in the theme editor
- Click "Add section" or "Add block"
- Look for "Festive Notifications" under App blocks
- Add it to your theme (typically in the theme layout or header)
- Save and publish
See docs/TESTING.md for detailed testing instructions including:
- Step-by-step guide to creating a test order
- How to verify webhook delivery in app logs
- How to check the Event Gateway dashboard for event processing
- How to verify notifications appear in the storefront
- Troubleshooting common issues
- Shopify triggers webhook: When an order is created, Shopify sends an
orders/createwebhook to the Event Gateway Source - Event Gateway receives and queues: The Event Gateway reliably receives and queues the webhook with automatic retries
- App processes webhook: The Event Gateway delivers the webhook to
webhooks.orders.create.tsx - PII filtering: The webhook handler extracts order data and uses
hookdeck-publisher.tsto:- Remove customer PII (name, email, address)
- Fetch product images from Shopify
- Create a clean notification payload
- Event publication: The app publishes the PII-free notification to the Event Gateway's Publish API with shop-specific routing
- Event Gateway forwarding: The Event Gateway queues and forwards the event to Ably's REST API via the configured destination
- Pub/Sub broadcast: Ably broadcasts the event to all subscribed clients on the shop-specific channel
- Storefront receives: The JavaScript in
notifications.jsreceives the event via Ably Realtime - UI update: The notification is displayed with product image and festive snowflake animations
The Shopify theme app extension consists of:
- Liquid template: Defines the HTML structure and holiday light animations
- JavaScript: Handles Ably connection, event subscriptions, and snowflake animations
- CSS: Compiled from SCSS, provides styling for animations and layout
npm run devThis starts:
- Remix development server
- Shopify CLI tunnel
- SASS compiler for extension styles
npm run buildnpm run deployThis deploys your app extensions to Shopify.
live-notifications/
├── app/
│ ├── routes/
│ │ ├── webhooks.orders.create.tsx # Order webhook handler
│ │ ├── app._index.tsx # App home page
│ │ └── ...
│ ├── helpers/
│ │ └── hookdeck-publisher.ts # Event Gateway publishing utilities
│ └── shopify.server.ts # Shopify app configuration
├── extensions/
│ └── live-notifications/
│ ├── blocks/
│ │ └── notifications.liquid # Theme block template
│ ├── assets/
│ │ ├── notifications.js # Client-side logic
│ │ └── notifications.css # Compiled styles
│ └── src/
│ └── notifications.scss # Source styles
├── scripts/
│ └── setup-hookdeck.ts # Automated connection setup
├── plans/
│ ├── hookdeck-ably-architecture.md # Architecture documentation
│ └── hookdeck-setup-architecture.md # Setup process documentation
├── docs/
│ └── TESTING.md # Testing guide
├── prisma/
│ └── schema.prisma # Database schema
├── shopify.app.toml # App configuration
└── package.json # Dependencies
- Remix - Full-stack web framework
- Shopify App Remix - Shopify app framework for Remix
- Hookdeck Event Gateway - Webhook infrastructure for reliable delivery and event routing
- Ably - Real-time pub/sub messaging platform
- Prisma - Database ORM
- Shopify Theme App Extensions - Storefront integration
- Shopify App Development
- Shopify Webhooks
- Shopify Theme App Extensions
- Shopify Admin GraphQL API
- Hookdeck Event Gateway Documentation
- Ably Documentation
- Remix Documentation
- Shopify App Tutorial
- Webhooks Best Practices
- Theme App Extension Tutorial
- Hookdeck Event Gateway Guide
- Ably Realtime Guide
- Security: The Ably API key is currently hardcoded in the client-side JavaScript. For production, implement token authentication
- Error Handling: Basic error handling is implemented; production apps should include comprehensive error handling and monitoring
- Scalability: This demo uses a simple SQLite database; production apps should use PostgreSQL or MySQL
- Shop-specific channels: The current implementation creates shop-specific Ably channels to isolate events between stores
This is a demonstration/tutorial project for educational purposes.
leggetter
Questions or Issues? This is a tutorial app - refer to the official documentation links above for detailed guidance on each technology used.
