Skip to content

Conversation

@dylandepass
Copy link
Contributor

@dylandepass dylandepass commented Jan 28, 2026

Summary

  • Fix Add to Cart for non-US store views (e.g., /ca/fr_ca/) by using store-specific localStorage keys.
  • Preserve existing US carts by keeping the original mage-cache-storage key for /us/en_us/.
  • Enable cart isolation between store views so users can maintain separate carts when switching between stores. This is mainly a requirement for the vitamix team to test across multiple sites. Although possible, customers are likely to switch between stores.

Problem

Add to Cart was failing on non-US stores because:

  1. The cart data in localStorage was being shared across all store views
  2. Hardcoded /us/en_us/ paths in legacy add-to-cart and affiliate coupon URLs
  3. GraphQL Store header was hardcoded to en_us. The commerce backend was receiving the wrong store context for non-US stores

Solution

Store-specific localStorage keys
/us/en_us/ -> mage-cache-storage (unchanged)
/ca/fr_ca/ -> mage-cache-storage-ca-fr_ca
/ca/en_us/ -> mage-cache-storage-ca-en_us

This applies to all three Magento cache keys: mage-cache-storage, mage-cache-timeout, and mage-cache-storage-section-invalidation.

Dynamic locale/language in URLs

  • Legacy add-to-cart endpoint now uses /${locale}/${language}/checkout/cart/add/...
  • Affiliate coupon URL now uses dynamic locale/language

Why this won't break the US store

  1. Explicit US check - The code explicitly checks for US store and returns an empty suffix:
if (locale === 'us' && language === 'en_us') {
   return '';  // Empty suffix = original key
}
  1. Fallback defaults to US - If URL parsing fails for any reason, it defaults to US values:
const locale = pathSegments[0] || 'us';
const language = pathSegments[1] || 'en_us';
  1. No hardcoded keys remain - All localStorage access goes through helper functions that respect the store-specific logic

  2. Existing US carts preserved - US store continues using mage-cache-storage, so existing cart data is untouched

Test URLs:

@aem-code-sync
Copy link

aem-code-sync bot commented Jan 28, 2026

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch and validate page speed.
In case there are problems, just click a checkbox below to rerun the respective action.

  • Re-run PSI checks
  • Re-sync branch
Commits

@aem-code-sync
Copy link

aem-code-sync bot commented Jan 28, 2026

Page Scores Audits Google
📱 /us/en_us/products/ascent-x2 PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI
🖥️ /us/en_us/products/ascent-x2 PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI

@dylandepass dylandepass changed the title Fix add to cart fix: add to cart Jan 28, 2026
@dylandepass dylandepass changed the title fix: add to cart fix: add to cart support for other regions Jan 30, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Add to Cart functionality for non-US store views (e.g., /ca/fr_ca/) by implementing store-specific localStorage keys while preserving backward compatibility for the US store. The fix addresses issues where cart data was being shared across all store views and hardcoded paths were preventing proper cart operations in non-US regions.

Changes:

  • Introduced store-specific localStorage keys for cart isolation (e.g., mage-cache-storage-ca-fr_ca for Canadian French)
  • Dynamically constructed locale/language paths in URLs for add-to-cart and affiliate coupon endpoints
  • Added comprehensive test coverage for cart storage isolation across different store views

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 10 comments.

File Description
tests/cart/storage.spec.js New comprehensive test suite verifying store-specific localStorage keys, cart isolation, and GraphQL Store header correctness
scripts/storage/util.js Core implementation of store-specific localStorage key generation with helper functions, replacing hardcoded constants
scripts/scripts.js Updated affiliate coupon URL to use dynamic locale/language instead of hardcoded /us/en_us/
scripts/minicart/cart.js Updated legacy add-to-cart URL construction to use dynamic locale/language, reducing code duplication

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 118 to 121
if (cartData && cartData['side-by-side']) {
expect(cartData['side-by-side'].cart_id).toBe('us-cart-abc123');
console.log('✓ US cart stored in mage-cache-storage with correct cart_id');
}
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test checks if cartData exists and has the expected cart_id, but if cartData is null or doesn't have the 'side-by-side' property, the test silently passes without asserting anything. Consider adding an assertion that cartData is not null before the conditional check, or restructure the test to fail if the expected data is not present.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I restructured the test to fail if the expected data is not present.

Comment on lines +109 to +110
// Wait for the cart redirect or network request
await page.waitForTimeout(2000);
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using page.waitForTimeout with hardcoded delays (2000ms) is generally considered an anti-pattern in Playwright tests. It makes tests slower and can lead to flaky tests. Consider using waitForResponse, waitForRequest, or waitForSelector with specific conditions instead.

Suggested change
// Wait for the cart redirect or network request
await page.waitForTimeout(2000);
// Wait until mage-cache-storage has a side-by-side entry (up to 2000ms)
await page
.waitForFunction(() => {
const storage = localStorage.getItem('mage-cache-storage');
if (!storage) return false;
try {
const data = JSON.parse(storage);
return !!data['side-by-side'];
} catch {
return false;
}
}, { timeout: 2000 })
.catch(() => {});

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I agree this is better or makes the test easier to reason about.. If the test becomes flaky and problem (which it's not) I will reconsider.

JSON.stringify((new Date(new Date().getTime() + minutesToExpire * 60000)).toISOString()),
);
window.dispatchEvent(new StorageEvent('storage', { key: COMMERCE_CACHE_STORAGE_KEY }));
window.dispatchEvent(new StorageEvent('storage', { key: cacheStorageKey }));
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Superfluous arguments passed to function StorageEvent.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's incorrect @Copilot.. These are valid arguments
https://developer.mozilla.org/en-US/docs/Web/API/StorageEvent/StorageEvent

Also, why did you link go to the first pull request? ;)

@davidnuescheler davidnuescheler self-requested a review January 31, 2026 21:03
@dylandepass dylandepass changed the base branch from main to staging3 February 3, 2026 17:52
@dylandepass dylandepass merged commit bdc1ef9 into staging3 Feb 3, 2026
2 checks passed
@dylandepass dylandepass deleted the fix-add-to-cart branch February 3, 2026 17:53
@dylandepass dylandepass restored the fix-add-to-cart branch February 4, 2026 16:18
@dylandepass dylandepass deleted the fix-add-to-cart branch February 4, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants