Skip to content

Commit c64e8e2

Browse files
kdaviduikfrandiox
andauthored
[2024-07 back-fix] 🍪 Hydrogen Cookie Migration for New Shopify Cookie Architecture (#3355)
* feat: cookie architecture updates * Add tracking cookies migration infrastructure This commit adds the infrastructure for migrating tracking cookies from legacy _shopify_y/_shopify_s cookies to consolidated encrypted cookies using Server-Timing headers. Key changes: - Add tracking-utils.ts with getTrackingValues() to read tracking values from Server-Timing headers via Performance API - Add server-timing.ts with utilities for detecting SFAPI proxy mode and server-returned tracking values - Update storefront client to forward tracking values via headers - Add sameDomainForStorefrontApi option for proxy detection - Update customer-privacy component to support new cookie migration - Add buyerIpSig to StorefrontHeaders type - Update useShopifyCookies with fetchTrackingValues option * Add E2E tests for tracking cookies migration This commit adds comprehensive E2E tests for the tracking cookies migration feature, including both new and legacy cookie scenarios. Test structure: - new-cookies/: Tests for the new consolidated cookie system - consent-tracking-accept/decline.spec.ts - privacy-banner-accept/decline/consent-change.spec.ts - privacy-banner-migration.spec.ts (migration from legacy cookies) - old-cookies/: Tests for legacy _shopify_y/_shopify_s cookies - consent-tracking-accept/decline.spec.ts - privacy-banner-accept/decline.spec.ts - smoke/: Basic smoke tests for cart and home page Also adds: - Unit tests for tracking-utils.ts and server-timing.ts - E2E fixtures for server setup and storefront mocking - Environment configurations for different consent scenarios - Updated playwright configuration * Fix: Delay PerfKit loading until consent is collected This fixes a bug where PerfKit would load before consent was collected, causing it to use stale tracking values. The fix delays PerfKit loading until after the consent collection callback is fired. Changes: - Add consentCollected state to AnalyticsProvider - Only render PerfKit after consentCollected is true - Update onVisitorConsentCollected callback to track consent state - Add sameDomainForStorefrontApi to Consent type * Add SFAPI proxy support to createRequestHandler - Update @shopify/remix-oxygen createRequestHandler with SFAPI proxy - Add new createRequestHandler export to @Shopify/hydrogen - Proxy automatically routes /api/.../graphql.json to Storefront API - Forward Set-Cookie and server-timing headers from subrequests - Set _sfapi_proxy server-timing header for document requests - New proxyStorefrontApiRequests option (default: true) * Update package-lock.json for version bumps * Align createRequestHandler with PR #3309 Updates both @Shopify/hydrogen and @shopify/remix-oxygen createRequestHandler to match the implementation in PR #3309: - Add collectTrackingInformation option (default: true) - Add warning when storefront instance is missing from context - Use appendServerTimingHeader utility instead of manual header - Move poweredByHeader append to after tracking header processing - Add TODO comments for future major version changes - Improve JSDoc documentation for all options * Add missing getTrackingValues export from hydrogen package Re-export getTrackingValues from @shopify/hydrogen-react to align with PR #3309 cookie migration implementation. * Add buyerIpSig to remix-oxygen StorefrontHeaders Add the buyerIpSig field to both the StorefrontHeaders type and getStorefrontHeaders function in remix-oxygen to align with the hydrogen package's StorefrontHeaders type. This fixes type compatibility when passing getStorefrontHeaders() result to createStorefrontClient(). * Add sec-purpose header check to remix-oxygen getStorefrontHeaders Align with hydrogen's getStorefrontHeaders to check sec-purpose first, then fall back to purpose. This ensures browser-initiated prefetches (via Speculation Rules API or <link rel="prefetch">) are properly detected. * Rename proxyStorefrontApiRequests to proxyStandardRoutes Aligns the parameter name with PR #3309 for consistency. * Update Playwright to 1.57.0 Fixes Chromium crashes (SIGTRAP/SEGV) on macOS 15 Sequoia when running e2e tests. The older version 1.40.1 had compatibility issues with the newer macOS version. * Fix e2e test bundle interception pattern for Vite pre-bundled deps Update the route interception pattern in setWithPrivacyBanner to match Vite's pre-bundled dependency path format. The previous pattern (**/@fs/**/hydrogen/dist/**/*.js) didn't match the actual paths served by Vite dev server (**/node_modules/.vite/deps/@shopify_hydrogen.js*). * Fix * fix * Fix create-hydrogen snapshot for TokenlessApi route Update the integration test snapshot to include the TokenlessApi route that was added in #2948 but the snapshot was never updated. Also includes skeleton template changes for the cookie migration backport: - Use createRequestHandler from @Shopify/hydrogen with proxyStandardRoutes - Minor formatting cleanup in root.tsx * Disable proxyStandardRoutes in classic-remix example The classic-remix example uses @shopify/remix-oxygen's createRequestHandler which now defaults to proxyStandardRoutes: true. This requires a storefront instance with specific methods that the classic-remix example doesn't provide. Setting proxyStandardRoutes: false restores the previous behavior and fixes the dev test. * Also disable collectTrackingInformation in classic-remix example The classic-remix example doesn't use the full Hydrogen stack, so disable both proxyStandardRoutes and collectTrackingInformation to avoid issues with the new request handler options. * Guard getSetCookie call for environments without Headers support Some environments like the classic Remix compiler may not have the getSetCookie method on their Headers implementation. * Remove redundant in skeleton template; update changesets to be more consistent with 2025-07 PR * Run e2e tests on CI (#3330) * Run e2e tests on CI * test: comment out checkout URl assertions until backend has updated --------- Co-authored-by: Kara Daviduik <kara.daviduik@shopify.com> * fix npm run build so that it works in worktrees * fix: add test cleanup to prevent canTrack() test pollution The useCustomerPrivacy hook sets up Object.defineProperty watchers on window.Shopify that persisted across tests, causing the canTrack() test to fail. The "renders its children" test ran first and established the property watcher, which then affected subsequent tests expecting window.Shopify to be undefined. Added afterEach cleanup hook to delete window.Shopify and window.privacyBanner between tests, ensuring proper test isolation. * fix: update E2E home page test selector for 2024.7 The test was written for a future version where product items use .product-item. In the 2024.7 skeleton template, the home page uses .recommended-product for product items instead. * update dependencies --------- Co-authored-by: Fran Dios <frankdiox@gmail.com>
1 parent a6e5b04 commit c64e8e2

57 files changed

Lines changed: 4773 additions & 146 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/cold-rules-wave.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@shopify/hydrogen': patch
3+
---
4+
5+
This version adds support for the new cookie system in Shopify (`_shopify_analytics` and `_shopify_marketing` http-only cookies). It is backward compatible and still supports the deprecated `_shopify_y` and `_shopify_s` cookies.
6+
7+
- `createRequestHandler` can now be used for every Hydrogen app, not only the ones deployed to Oxygen. It is now exported from `@shopify/hydrogen`.
8+
- A new Storefront API proxy is now available in Hydrogen's `createRequestHandler`. This will be used to obtain http-only cookies from Storefront API. In general, it should be transparent but it can be disabled with the `proxyStandardRoutes` option.
9+
- `Analytics.Provider` component and `useCustomerPrivacy` hook now make a request internally to the mentioned proxy to obtain cookies in the storefront domain.

.changeset/remix-oxygen-proxy.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@shopify/remix-oxygen': minor
3+
---
4+
5+
6+
Support Shopify's new consolidated cookie architecture. Adds built-in Storefront API proxy support to `createRequestHandler`.

.changeset/rotten-bobcats-grab.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@shopify/hydrogen-react': patch
3+
---
4+
5+
New export `getTrackingValues` to obtain information for analytics and marketing. Use this instead of `getShopifyCookies` (which is now deprecated).
6+
7+
`useShopifyCookies` now accepts a `fetchTrackingValues` parameter that can be used to make a Storefront API request and obtain Shopify http-only cookies, `_shopify_analytics` and `_shopify_marketing` (which replace the deprecated `_shopify_y` and `_shopify_s` cookies).

.changeset/two-melons-design.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/hydrogen': patch
3+
---
4+
5+
Fixed a number of issues related to irregular behaviors between Privacy Banner and Hydrogen's analytics events.

.github/workflows/ci.yml

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,47 @@ jobs:
9393
- name: 🧑‍💻 CLI manifest check
9494
run: 'test -z "$(git status --porcelain "packages/cli/oclif.manifest.json" )" || { echo -e "Run npm generate:manifest in packages/cli before pushing new commands or flags. Diff here:\n\n$(git diff)" ; exit 1; }'
9595

96-
test:
96+
test_e2e:
97+
name: ⬣ E2E tests
98+
runs-on: ubuntu-latest
99+
timeout-minutes: 15
100+
concurrency:
101+
group: ci-e2e-${{ github.ref }}
102+
cancel-in-progress: true
103+
steps:
104+
- name: ⬇️ Checkout repo
105+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
106+
107+
- name: ⎔ Setup node
108+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
109+
with:
110+
node-version-file: '.nvmrc'
111+
cache: 'npm'
112+
cache-dependency-path: '**/package-lock.json'
113+
114+
- name: 📥 Install dependencies
115+
run: |
116+
npm ci
117+
npm rebuild
118+
119+
- name: 📦 Build packages and templates
120+
run: SHOPIFY_HYDROGEN_FLAG_LOCKFILE_CHECK=false npm run build:all
121+
122+
- name: 🎭 Install Playwright Chromium
123+
run: npx playwright install chromium --with-deps
124+
125+
- name: 🧪 Run E2E tests
126+
run: npx playwright test --workers=1
127+
128+
- name: 📤 Upload Playwright Report
129+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
130+
if: ${{ !cancelled() }}
131+
with:
132+
name: playwright-report
133+
path: playwright-report/
134+
retention-days: 30
135+
136+
test_unit:
97137
name: ⬣ Unit tests
98138
runs-on: ubuntu-latest
99139
timeout-minutes: 15
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SESSION_SECRET="mock-session"
2+
PUBLIC_CHECKOUT_DOMAIN="checkout.hydrogen.shop"
3+
PUBLIC_STORE_DOMAIN="checkout.hydrogen.shop"
4+
PUBLIC_STOREFRONT_API_TOKEN="b97a750a8afa8fe33f2b4012cb3a9f6f"
5+
PUBLIC_STOREFRONT_ID="1000014875"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SESSION_SECRET="mock-session"
2+
PUBLIC_CHECKOUT_DOMAIN="www.iwantacheapdomainfortesting12345.club"
3+
PUBLIC_STORE_DOMAIN="www.iwantacheapdomainfortesting12345.club"
4+
PUBLIC_STOREFRONT_API_TOKEN="2aac2e4420f32ba0c7dadf55c7cc387b"
5+
PUBLIC_STOREFRONT_ID="1000070232"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SESSION_SECRET="mock-session"
2+
PUBLIC_CHECKOUT_DOMAIN="www.kara2345.xyz"
3+
PUBLIC_STORE_DOMAIN="www.kara2345.xyz"
4+
PUBLIC_STOREFRONT_API_TOKEN="8eece95833df895900c1b285987c7f40"
5+
PUBLIC_STOREFRONT_ID="1000070242"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SESSION_SECRET="mock-session"
2+
PUBLIC_CHECKOUT_DOMAIN="checkout.daviduik.com"
3+
PUBLIC_STORE_DOMAIN="checkout.daviduik.com"
4+
PUBLIC_STOREFRONT_API_TOKEN="a79d329fc13657352c6e4734e5d4ca75"
5+
PUBLIC_STOREFRONT_ID="1000061747"

e2e/envs/.env.mockShop

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SESSION_SECRET="mock-session"
2+
PUBLIC_CHECKOUT_DOMAIN="mock.shop"
3+
PUBLIC_STORE_DOMAIN="mock.shop"
4+
PUBLIC_STOREFRONT_API_TOKEN=""
5+
PUBLIC_STOREFRONT_ID=""

0 commit comments

Comments
 (0)