Storefront Cart API and Shopify Liquid Themes Cart -> How to make them sync?

Building an AI chatbot embedded in Shopify storefronts via Shadow DOM, and running into a fundamental cart sync problem. Would love input from anyone whoโ€™s solved this.

๐—ง๐—ต๐—ฒ ๐—ฃ๐—ฟ๐—ผ๐—ฏ๐—น๐—ฒ๐—บ

We are building a conversational commerce chatbot that helps users discover products and add to cart. Our Agent backend uses the Storefront API to handle cart operations. But weโ€™re hitting a wall: the Storefront API cart and Shopifyโ€™s native theme cart (AJAX Cart / session cookie-based) are two completely isolated systems.

Items added via the chatbot donโ€™t show up on the /cart page.

๐—ช๐—ต๐—ฎ๐˜ ๐—ช๐—ฒโ€™๐˜ƒ๐—ฒ ๐—ฅ๐˜‚๐—น๐—ฒ๐—ฑ ๐—ข๐˜‚๐˜

-> Multipass (requires Shopify Plus. Not an option for our merchants)
โ†’ Calling /cart/add.js from backend (server has no session cookie)

What is working but feels like a hack
โ†’ Relying on Shopifyโ€™s session cart

๐—ง๐—ต๐—ฟ๐—ฒ๐—ฒ ๐—”๐—ฝ๐—ฝ๐—ฟ๐—ผ๐—ฎ๐—ฐ๐—ต๐—ฒ๐˜€ ๐—ช๐—ฒโ€™๐—ฟ๐—ฒ ๐—–๐—ผ๐—ป๐˜€๐—ถ๐—ฑ๐—ฒ๐—ฟ๐—ถ๐—ป๐—ด

:one: AJAX Cart API + postMessage bridge
Chatbot sends cart intent to parent Shopify page via postMessage. Parent page calls /cart/add.js with session cookie intact.

:two: Custom Cart UI (Storefront API as source of truth)
Build a custom cart drawer injected via App Embed Block. Agent returns only a cartId. Custom cart UI fetches cart state directly from Storefront API using that cartId. cartId persists in localStorage per user. No session cookies, no shared state. Fully isolated per user.

๐—ค๐˜‚๐—ฒ๐˜€๐˜๐—ถ๐—ผ๐—ป๐˜€ ๐—ณ๐—ผ๐—ฟ ๐˜๐—ต๐—ฒ ๐—ฐ๐—ผ๐—บ๐—บ๐˜‚๐—ป๐—ถ๐˜๐˜†

-> For those whoโ€™ve built chatbot or AI agent integrations on Shopify: Is the custom cart (Storefront API + localStorage) genuinely the cleaner long-term architecture, or does the AJAX Cart approach hold up well enough at scale?

-> Any gotchas with the custom cart approach we should anticipate beyond the obvious (cartId expiry, native ATC button interception, suppressing the theme cart UI)?

-> On Shopifyโ€™s Universal Cart (part of Shopify for Agents, currently in early access): it enables a single persistent cart across AI agent surfaces and multiple merchants. For a chatbot like ours thatโ€™s embedded directly in a merchantโ€™s Shopify storefront, does Universal Cart change this architecture entirely? Or is it solving a different problem (cross-merchant aggregation for external AI surfaces like Google/Gemini) rather than the storefront-embedded chatbot sync problem weโ€™re dealing with?

The documentation doesnโ€™t always surface these nuances. Would love to hear from anyone navigating the same space.

Hey @Khyati_Thakur, thanks for posting! I looked into this for you internally and youโ€™ve diagnosed this correctly. The native theme cart (the Ajax API session/cookie cart) and a Storefront API cart are two separate cart objects, and thereโ€™s no native sync between them. The Ajax cart token isnโ€™t a key you can feed into the Storefront API either, so cartCreate always makes a brand new cart rather than interacting with an existing /cart one. This is by design.

For a chatbot whose backend already owns cart state, the custom cart drawer with the Storefront API as source of truth is the cleaner long-term option. The Storefront cart returns a checkoutUrl that routes to the same Shopify web checkout, so you can skip the theme cart entirely for purchase completion and just suppress the native cart UI. The one thing to watch closely is that the cart ID is <token>?key=<secret>, and that secret must never be exposed client side. If you persist the full cartId in localStorage and query from the browser, youโ€™re leaking it; if you drop the key, buyer PII gets stripped and mutations fail. Most setups keep the secret on the backend and only expose what the client needs.

On Universal Cart, your instinct is right that itโ€™s solving a different problem. Itโ€™s an agent-first, cross-merchant cart accessed over UCP/MCP for off-storefront surfaces, keyed to agent and buyer identity rather than a storefront session. It isnโ€™t an extension point for the Online Store cart and wonโ€™t sync into a merchantโ€™s native /cart, so it doesnโ€™t change the storefront-embedded architecture youโ€™re working through here.