fix: include items array in purchase dataLayer#8339
Conversation
🎭 Playwright Tests:
|
🎨 Storybook Build Status✅ Build completed successfully! ⏰ Completed at: 01/27/2026, 08:57:07 PM UTC 🔗 Links🎉 Your Storybook is ready for review! |
📝 WalkthroughWalkthroughThe PR refactors the dataLayer purchase event payload structure in the subscription composable. Item-related fields ( Changes
Possibly related PRs
Suggested reviewers
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates subscription purchase tracking to include GA4-compliant items array format. Previously, item properties were sent as top-level fields in the dataLayer event; now they are properly nested within an items array as required by GA4 purchase event specifications.
Changes:
- Restructured the purchase dataLayer event to nest item properties (
item_id,item_name,item_category,item_variant,price,quantity) within anitemsarray - Updated the corresponding unit test to reflect the new items array structure
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/platform/cloud/subscription/composables/useSubscription.ts | Refactored purchase event to use GA4-style items array instead of flat item properties |
| src/platform/cloud/subscription/composables/useSubscription.test.ts | Updated test assertions to expect items array structure |
| items: [ | ||
| { | ||
| item_id: 'monthly_creator', | ||
| item_variant: 'monthly', | ||
| item_category: 'subscription', | ||
| quantity: 1 | ||
| } | ||
| ] |
There was a problem hiding this comment.
The test assertion is incomplete. The implementation includes item_name and price fields in the items array (lines 132 and 135 in useSubscription.ts), but the test doesn't verify these fields are present. For a monthly creator subscription, these should be:
item_name: The translated plan name (e.g., "Creator")price: 35 (the monthly price for creator tier)
Additionally, the test should verify the top-level value field is set to 35.
Bundle Size ReportSummary
Category Glance Per-category breakdownApp Entry Points — 23.6 kB (baseline 23.6 kB) • ⚪ 0 BMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 960 kB (baseline 960 kB) • ⚪ 0 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 80.7 kB (baseline 80.7 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 9 added / 9 removed Panels & Settings — 470 kB (baseline 470 kB) • 🟢 -8 BConfiguration panels, inspectors, and settings screens
Status: 12 added / 12 removed User & Accounts — 3.94 kB (baseline 3.94 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 3 added / 3 removed Editors & Dialogs — 2.9 kB (baseline 2.9 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 2 added / 2 removed UI Components — 33.7 kB (baseline 33.7 kB) • ⚪ 0 BReusable component library chunks
Status: 4 added / 4 removed Data & Services — 2.7 MB (baseline 2.7 MB) • 🔴 +25 BStores, services, APIs, and repositories
Status: 9 added / 9 removed Utilities & Hooks — 25.5 kB (baseline 25.5 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 7 added / 7 removed Vendor & Third-Party — 10.7 MB (baseline 10.7 MB) • ⚪ 0 BExternal libraries and shared vendor chunks
Other — 7.04 MB (baseline 7.04 MB) • 🟢 -200 BBundles that do not match a named category
Status: 37 added / 37 removed |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/platform/cloud/subscription/composables/useSubscription.test.ts`:
- Around line 240-247: The test currently asserts the items payload only
contains item_id, item_variant, item_category, and quantity for the item with
item_id 'monthly_creator' but is missing assertions for item_name and price;
update the test in useSubscription.test.ts to also assert that
items[0].item_name and items[0].price are present (e.g.,
expect(payload.items[0].item_name).toBeDefined() or equal the expected string,
and expect(payload.items[0].price).toBeDefined() or equal the expected numeric
value) so the spec catches regressions that remove those fields.
| items: [ | ||
| { | ||
| item_id: 'monthly_creator', | ||
| item_variant: 'monthly', | ||
| item_category: 'subscription', | ||
| quantity: 1 | ||
| } | ||
| ] |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Locate and read the test file to see the actual content at lines 240-247
fd -e test.ts -p "useSubscription" | head -5Repository: Comfy-Org/ComfyUI_frontend
Length of output: 374
🏁 Script executed:
# Search for the useSubscription.test.ts file
find . -name "useSubscription.test.ts" -type fRepository: Comfy-Org/ComfyUI_frontend
Length of output: 139
🏁 Script executed:
# Try a broader search for subscription test files
fd "useSubscription" -t fRepository: Comfy-Org/ComfyUI_frontend
Length of output: 728
🏁 Script executed:
# Read the test file, focusing on lines 240-247 and surrounding context
sed -n '230,260p' src/platform/cloud/subscription/composables/useSubscription.test.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 976
🏁 Script executed:
# Get total line count to understand the file size
wc -l src/platform/cloud/subscription/composables/useSubscription.test.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 141
🏁 Script executed:
# Search for the test containing the items payload to understand context
rg "item_id.*monthly_creator" src/platform/cloud/subscription/composables/useSubscription.test.ts -A 10 -B 10Repository: Comfy-Org/ComfyUI_frontend
Length of output: 636
🏁 Script executed:
# Read the useSubscription.ts implementation to see what's being pushed to dataLayer
rg "item_id.*monthly_creator" src/platform/cloud/subscription/composables/useSubscription.ts -A 10 -B 10Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Broader search for dataLayer push in the implementation
rg "dataLayer" src/platform/cloud/subscription/composables/useSubscription.ts -A 5 -B 5Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Search for item_name or price being set in subscription composables
rg "item_name|item_price|price.*subscription" src/platform/cloud/subscription/ -t tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 163
🏁 Script executed:
# Read the implementation file to see the full dataLayer payload being constructed
cat -n src/platform/cloud/subscription/composables/useSubscription.ts | sed -n '1,100p'Repository: Comfy-Org/ComfyUI_frontend
Length of output: 4233
🏁 Script executed:
# Search for where the dataLayer event is constructed - look for item_name context
rg "item_name" src/platform/cloud/subscription/composables/useSubscription.ts -B 5 -A 5Repository: Comfy-Org/ComfyUI_frontend
Length of output: 345
🏁 Script executed:
# Search for price in the subscription context
rg "price" src/platform/cloud/subscription/composables/ -t ts -B 2 -A 2Repository: Comfy-Org/ComfyUI_frontend
Length of output: 519
🌐 Web query:
GA4 ecommerce purchase event items array required fields documentation
💡 Result:
For GA4 ecommerce (including the purchase event), the items parameter is an array of Item objects. For each object in items, the only required item-level fields are:
item_id(string) — required ifitem_nameisn’t sentitem_name(string) — required ifitem_idisn’t sent
In other words: each item must include at least one of item_id or item_name; everything else in the item object is optional. [1]
Related implementation notes from Google’s docs:
purchaseshould include the event-levelitemsarray; if required ecommerce parameters are missing, GA4 may treat it as a custom event rather than an ecommerce event. [3]itemscan include up to 200 items per event. [2]- You can add up to 27 custom item-scoped parameters (in addition to Google’s predefined item parameters). [4]
Sources: Google Analytics developer documentation. [1] [2] [3] [4]
🏁 Script executed:
# Let me get more context around the dataLayer push to understand the full picture
rg "pushDataLayerEvent\|dataLayer.push" src/platform/cloud/subscription/composables/useSubscription.ts -B 10 -A 10Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Search for the dataLayer event construction with different pattern
rg "event.*purchase" src/platform/cloud/subscription/composables/useSubscription.ts -B 15 -A 5Repository: Comfy-Org/ComfyUI_frontend
Length of output: 801
🏁 Script executed:
# Look at the entire section where the items array is built
sed -n '100,250p' src/platform/cloud/subscription/composables/useSubscription.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 4294
Assert item_name and price in the items payload.
The test omits assertions for fields that are being sent in the actual payload. Add assertions to verify item_name and price presence to catch regressions where these fields might be removed.
Suggested test update
items: [
{
item_id: 'monthly_creator',
+ item_name: expect.any(String),
item_variant: 'monthly',
item_category: 'subscription',
+ price: expect.any(Number),
quantity: 1
}
]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| items: [ | |
| { | |
| item_id: 'monthly_creator', | |
| item_variant: 'monthly', | |
| item_category: 'subscription', | |
| quantity: 1 | |
| } | |
| ] | |
| items: [ | |
| { | |
| item_id: 'monthly_creator', | |
| item_name: expect.any(String), | |
| item_variant: 'monthly', | |
| item_category: 'subscription', | |
| price: expect.any(Number), | |
| quantity: 1 | |
| } | |
| ] |
🤖 Prompt for AI Agents
In `@src/platform/cloud/subscription/composables/useSubscription.test.ts` around
lines 240 - 247, The test currently asserts the items payload only contains
item_id, item_variant, item_category, and quantity for the item with item_id
'monthly_creator' but is missing assertions for item_name and price; update the
test in useSubscription.test.ts to also assert that items[0].item_name and
items[0].price are present (e.g.,
expect(payload.items[0].item_name).toBeDefined() or equal the expected string,
and expect(payload.items[0].price).toBeDefined() or equal the expected numeric
value) so the spec catches regressions that remove those fields.
This reverts commit ef8657b.
Include GA4-style
itemspayload for subscription purchase events so GTM receives the full item array.So, to align with GA4's ecommerce standards, we changed it to an items array: https://developers.google.com/analytics/devguides/collection/ga4/item-scoped-ecommerce