Skip to content

Commit 185e237

Browse files
committed
feat(rum_shopify): added RUM Shopify integration docs
1 parent 538726c commit 185e237

4 files changed

Lines changed: 256 additions & 0 deletions

File tree

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ code-coverage.datadog.yml @DataDog/agent-integr
192192
/rum_react_native/ @DataDog/rum-app @DataDog/rum-mobile
193193
/rum_roku/ @DataDog/rum-app @DataDog/rum-mobile
194194
/rum_salesforce_lwc/ @DataDog/rum-app @DataDog/rum-browser
195+
/rum_shopify/ @DataDog/rum-app @DataDog/rum-browser
195196
/rum_vue/ @DataDog/rum-app @DataDog/rum-browser
196197
/rundeck/ forrest@rundeck.com
197198
/scalr/ @soltysss @DataDog/ecosystems-review

rum_shopify/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# CHANGELOG - Shopify
2+
3+
## 1.0.0
4+
5+
**_Added_**:
6+
7+
* Initial Shopify RUM Integration Tile.

rum_shopify/README.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# Shopify Integration
2+
3+
## Overview
4+
5+
Instrument your Shopify store with Datadog Real User Monitoring using the Datadog RUM Shopify bundle. One bundle covers both surfaces of a Shopify store:
6+
7+
- **Storefront pages** (`/`, `/products/*`, `/collections/*`, etc.) — added via a Theme Liquid snippet. Full RUM feature set: views, resources, long tasks, user interactions, errors, and Session Replay.
8+
- **Checkout pages** (`/checkouts/*`, `/checkout`) — added via a Custom Pixel. Shopify deprecated `checkout.liquid` in August 2024, so checkout pages cannot be reached by theme edits at all; a [Web Pixel][5] running in a sandboxed iframe is the only mechanism that can observe them.
9+
10+
Use both deployment paths together for full-funnel coverage.
11+
12+
## Setup
13+
14+
### Prerequisites
15+
16+
Before you begin, gather the following Datadog RUM values:
17+
18+
- A Datadog RUM Application ID
19+
- A Datadog RUM Client Token
20+
- A Datadog site, such as `datadoghq.com`
21+
22+
You can get those values in Datadog under **Digital Experience > Real User Monitoring > Manage Applications > Set Up Manually**.
23+
24+
You'll also need:
25+
26+
- Admin access to your Shopify store (**Settings** and **Online Store > Themes**).
27+
- For the Custom Pixel path: access to **Settings > Customer events** in Shopify Admin.
28+
29+
### Installation and Configuration
30+
31+
#### Theme Liquid Setup
32+
33+
Use this path to cover storefront pages (product, collection, cart, home).
34+
35+
##### Steps
36+
37+
1. In Shopify Admin, go to **Online Store > Themes**.
38+
2. On your live theme, click the **** menu, then **Edit code**.
39+
3. Open `layout/theme.liquid`.
40+
4. Paste the following snippet right before the closing `</head>` tag, replacing the placeholder values with your Datadog RUM configuration:
41+
42+
```html
43+
<script>
44+
(function (h, o, u, n, d) {
45+
h = h[d] = h[d] || { q: [], onReady: function (c) { h.q.push(c) } }
46+
d = o.createElement(u); d.async = 1; d.src = n
47+
d.crossOrigin = 'anonymous'
48+
n = o.getElementsByTagName(u)[0]; n.parentNode.insertBefore(d, n)
49+
})(
50+
window,
51+
document,
52+
'script',
53+
'https://www.datadoghq-browser-agent.com/{{< region-param key="dd_datacenter_lowercase" code="true" >}}/v7/datadog-rum-shopify.js',
54+
'DD_RUM'
55+
);
56+
57+
DD_RUM.onReady(function () {
58+
DD_RUM.init({
59+
applicationId: '<YOUR_DATADOG_APPLICATION_ID>',
60+
clientToken: '<YOUR_DATADOG_CLIENT_TOKEN>',
61+
site: '{{< region-param key="dd_site" code="true" >}}',
62+
service: '<YOUR_SERVICE_NAME>',
63+
env: '<YOUR_ENV_NAME>',
64+
version: '1.0.0',
65+
sessionSampleRate: 100,
66+
sessionReplaySampleRate: 100,
67+
trackUserInteractions: true,
68+
trackResources: true,
69+
trackLongTasks: true,
70+
defaultPrivacyLevel: 'mask-user-input',
71+
})
72+
DD_RUM.startSessionReplayRecording()
73+
})
74+
</script>
75+
```
76+
77+
5. Save the file.
78+
79+
##### Out-of-the-box functionality
80+
81+
`DD_RUM.init()` here behaves exactly like the regular [`@datadog/browser-rum`][6] package. You get:
82+
83+
- Automatic view tracking as visitors navigate storefront pages.
84+
- Web Vitals, resource timing, long tasks, and automatic click tracking.
85+
- Session Replay recording.
86+
- Runtime error tracking (`window.onerror`, `unhandledrejection`).
87+
88+
##### Limitations
89+
90+
- **No checkout coverage.** Checkout, Thank You / Order Status, and Customer Account pages are fully controlled by Shopify and cannot be reached by any Liquid edit. Use the [Custom Pixel Setup](#custom-pixel-setup) below for that funnel.
91+
- Theme code changes require re-editing `theme.liquid` on every theme update or theme switch — there's no install-once mechanism on this path.
92+
93+
#### Custom Pixel Setup
94+
95+
Use this path to cover checkout pages (`/checkouts/*`, `/checkout`). It runs inside a Shopify **Custom Pixel**, a sandboxed `<iframe sandbox="allow-scripts allow-forms">` that Shopify injects to observe checkout events — the only place JavaScript can run on checkout pages at all.
96+
97+
##### Steps
98+
99+
1. In Shopify Admin, go to **Settings > Customer events**.
100+
2. Click **Add custom pixel**, give it a name, and open its code editor.
101+
3. Paste the following snippet, replacing the placeholder values with your Datadog RUM configuration:
102+
103+
```javascript
104+
(function (h, o, u, n, d) {
105+
h = h[d] = h[d] || { q: [], onReady: function (c) { h.q.push(c) } }
106+
d = o.createElement(u); d.src = n
107+
d.crossOrigin = 'anonymous'
108+
n = o.getElementsByTagName(u)[0]; n.parentNode.insertBefore(d, n)
109+
})(
110+
window,
111+
document,
112+
'script',
113+
'https://www.datadoghq-browser-agent.com/{{< region-param key="dd_datacenter_lowercase" code="true" >}}/v7/datadog-rum-shopify.js',
114+
'DD_RUM'
115+
)
116+
117+
DD_RUM.onReady(function () {
118+
DD_RUM.init({
119+
applicationId: '<YOUR_DATADOG_APPLICATION_ID>',
120+
clientToken: '<YOUR_DATADOG_CLIENT_TOKEN>',
121+
site: '{{< region-param key="dd_site" code="true" >}}',
122+
service: '<YOUR_SERVICE_NAME>',
123+
env: '<YOUR_ENV_NAME>',
124+
version: '1.0.0',
125+
sessionSampleRate: 100,
126+
shopifyAnalytics: analytics, // the Custom Pixel's `analytics` global — see note below
127+
})
128+
})
129+
```
130+
131+
4. Save the pixel, then set its required consent category under **Settings** for the pixel (e.g. Analytics) to match your store's privacy configuration — the bundle does not add its own consent gate; it defers entirely to whatever the merchant declares in Shopify's Pixel Manager.
132+
133+
**Note on `shopifyAnalytics`:** `analytics` is a bare global that only exists inside a Custom Pixel's code editor scope — pass it straight through as shown.
134+
135+
##### Out-of-the-box functionality
136+
137+
Once `shopifyAnalytics` is set, the bundle automatically:
138+
139+
- Starts a RUM view on each checkout step (bound to Shopify's `page_viewed` standard event).
140+
- Converts Shopify's `clicked` DOM event into a RUM click action, with correct position data.
141+
- Converts Shopify's `ui_extension_errored` event (a checkout UI extension crashing) into a RUM error, tagged with the failing extension's name, target, and type.
142+
- Continues the storefront session: the sandbox shares the top frame's cookie jar, so if a visitor already has a `_dd_s` session cookie from the Theme Liquid snippet, checkout events land in that same session.
143+
- Is a no-op in effect on storefront pages: Shopify fires the pixel's `page_viewed` event on every page, not just checkout, but the bundle only calls `startView` for checkout-path URLs — so no duplicate session or duplicate view is created alongside the Theme Liquid instance.
144+
145+
##### Instrumenting extra Shopify events
146+
147+
The snippet above only wires up the three events the bundle binds automatically. Shopify's [standard events][7] cover the full checkout funnel — `checkout_started`, `checkout_contact_info_submitted`, `checkout_shipping_info_submitted`, `payment_info_submitted`, `checkout_completed`, `alert_displayed` and more. Subscribe to any of them yourself, using `DD_RUM.onReady()` to queue calls made before the SDK has finished loading:
148+
149+
```javascript
150+
analytics.subscribe('checkout_completed', (event) => {
151+
const checkout = event.data.checkout
152+
DD_RUM.onReady(() =>
153+
DD_RUM.addAction('checkout_completed', {
154+
orderId: checkout?.order?.id,
155+
totalPrice: checkout?.totalPrice,
156+
})
157+
)
158+
})
159+
160+
analytics.subscribe('checkout_contact_info_submitted', (event) => {
161+
const checkout = event.data.checkout
162+
DD_RUM.onReady(() => {
163+
if (checkout?.email) {
164+
DD_RUM.setUser({ email: checkout.email }) // capture the guest email here
165+
}
166+
DD_RUM.addAction('checkout_contact_info_submitted', { checkoutToken: checkout?.token })
167+
})
168+
})
169+
```
170+
171+
You can also emit and subscribe to [custom events][8] the same way.
172+
173+
##### Limitations
174+
175+
- **No Session Replay or Profiling.** The sandbox iframe has no real checkout DOM — recording or profiling it would capture nothing meaningful. Both are force-disabled regardless of what you pass to `init()`.
176+
- **No Web Vitals, resource timing, or runtime JS errors.** `PerformanceObserver`, `fetch`/`XMLHttpRequest` instrumentation, and `window.onerror`/`unhandledrejection` all observe the sandbox iframe itself, not the checkout page's main thread — that boundary can't be crossed from a Custom Pixel.
177+
- **Click actions are partial.** Only Shopify's basic `clicked` DOM event is available (no automatic DOM click listener, since there's no real DOM to listen on):
178+
- Emitted for inputs, links, and buttons — not for empty space or plain text.
179+
- Not emitted for payment card fields (card number, expiration, CVC, name on card) or the "Sign in" link.
180+
- Not emitted for a second click on a field that's already focused.
181+
- **Advanced DOM Events are unavailable.** Shopify restricts that API to apps approved for it in the Partner Dashboard — a bar that doesn't apply to (and can't be met by) a Custom Pixel.
182+
- **Checkout-path detection is regex-based**, matching `/checkouts?/` with an optional two-letter locale prefix (e.g. `/en/checkout`). A store with a non-standard checkout URL structure won't currently have an override flag to adjust it.
183+
184+
### Validate the Installation
185+
186+
#### Storefront (Theme Liquid)
187+
188+
1. Open your storefront in a new browser session with developer tools open.
189+
2. Confirm `datadog-rum-shopify.js` loads successfully (Network tab) and `window.DD_RUM` is defined (Console tab).
190+
3. Navigate between a few storefront pages (home, a product, the cart).
191+
4. In Datadog, open **Digital Experience > RUM Explorer**, filter by your configured `service` and `env`.
192+
5. Confirm view events appear for each page you visited, and that a Session Replay recording is available for the session.
193+
194+
#### Checkout (Custom Pixel)
195+
196+
1. Place a test order (or go far enough into checkout to trigger `checkout_started`) on a storefront that has the Custom Pixel configured.
197+
2. In the RUM Explorer, filter by the same `service`/`env` and look for views whose URL is under `/checkouts/`.
198+
3. Confirm the view URL matches the real checkout URL (not a sandbox/iframe address) — this validates the `page_viewed`-driven `startView` binding is working.
199+
4. Click a few checkout fields/buttons during the test run, then confirm corresponding click actions appear on the view.
200+
5. If you added extra event subscriptions (see [Instrumenting extra Shopify events](#instrumenting-extra-shopify-events)), confirm their custom actions or user attributes (e.g. `checkout_completed`, the identified email from `setUser`) show up on the same view/session.
201+
6. If nothing appears: check the pixel's consent category under **Settings > Customer events** — in opt-in (GDPR-style) regions, Shopify won't load the sandbox at all until the visitor consents, so no events fire until then.
202+
203+
## Troubleshooting
204+
205+
Need help? Contact [Datadog Support][3].
206+
207+
[1]: https://shopify.dev/docs/api/web-pixels-api
208+
[2]: https://docs.datadoghq.com/help/
209+
[3]: https://docs.datadoghq.com/help/
210+
[4]: https://docs.datadoghq.com/getting_started/site/#access-the-datadog-site
211+
[5]: https://shopify.dev/docs/api/web-pixels-api
212+
[6]: https://github.com/DataDog/browser-sdk/blob/main/packages/rum/README.md
213+
[7]: https://shopify.dev/docs/api/web-pixels-api/standard-events
214+
[8]: https://shopify.dev/docs/api/web-pixels-api/emitting-data

rum_shopify/manifest.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"manifest_version": "2.0.0",
3+
"app_uuid": "8af53d79-71ee-418a-97db-e2224c590002",
4+
"app_id": "rum-shopify",
5+
"owner": "rum-browser",
6+
"display_on_public_website": true,
7+
"tile": {
8+
"overview": "README.md#Overview",
9+
"configuration": "README.md#Setup",
10+
"support": "README.md#Troubleshooting",
11+
"changelog": "CHANGELOG.md",
12+
"description": "Monitor Shopify storefront and checkout pages using Datadog RUM",
13+
"title": "Shopify (RUM)",
14+
"media": [],
15+
"classifier_tags": [
16+
"Category::Metrics",
17+
"Category::Network",
18+
"Category::Tracing",
19+
"Supported OS::Android",
20+
"Supported OS::Linux",
21+
"Supported OS::Windows",
22+
"Supported OS::iOS",
23+
"Supported OS::macOS",
24+
"Offering::Integration"
25+
]
26+
},
27+
"author": {
28+
"support_email": "help@datadoghq.com",
29+
"name": "Datadog",
30+
"homepage": "https://www.datadoghq.com",
31+
"sales_email": "info@datadoghq.com"
32+
},
33+
"assets": {}
34+
}

0 commit comments

Comments
 (0)