Skip to content

Commit f4250ab

Browse files
kdaviduikfrandiox
andauthored
[2025-01 back-fix] 🍪 Hydrogen Cookie Migration for New Shopify Cookie Architecture (#3354)
* [2025-01 back-fix] 🍪 Hydrogen Cookie Migration for New Shopify Cookie Architecture (#3332) * 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 * test: update playwright config so that in CI we will get full traces to be able to easily debug failures * Run npm install (with npm v10) --------- Co-authored-by: Fran Dios <frankdiox@gmail.com>
1 parent 8401911 commit f4250ab

File tree

57 files changed

+4738
-145
lines changed

Some content is hidden

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

57 files changed

+4738
-145
lines changed

.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: always()
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)