Why “headless wishlist” is a different problem
A Hydrogen storefront or a custom headless stack often uses the Storefront API for catalog, cart, and content. That does not automatically give you a safe, portable wishlist that:
- Trusts identity from Shopify (not a client-supplied customer id in JSON)
- Matches what the Online Store theme does when the same shopper logs in elsewhere
- Stays in your Shopify estate as metaobjects, not a second vendor database
Many hosted wishlist apps optimize for Liquid themes and app blocks. Headless becomes an afterthought: separate endpoints, weaker docs, or “use our JavaScript” in a world where your React server owns the session.
SaveLayer takes the opposite approach: the same save operations (save, list, remove, and related flows) run through one service path no matter which ingress you use. What changes per channel is how Shopify proves who the customer is, not what a wishlist means in your admin.
SaveLayer across surfaces
| Surface | How Shopify proves the customer | SaveLayer ingress | Same save model? |
|---|---|---|---|
| Online Store (theme, OS 2.0) | Shopify session via app proxy (signed URLs, logged-in context) | /proxy/api/* on the app; window.SaveLayer in the storefront |
Yes (metaobjects, shared contracts) |
| Headless (Hydrogen, custom stack) | Backend-only exchange with a valid Customer Account API access token (not legacy Storefront customer access token) | POST /api/headless/auth/exchange, then /api/headless/* with Authorization: Bearer (short-lived SaveLayer JWT) |
Yes |
| Customer account UI extensions | Shopify session token via authenticate.public.customerAccount at exchange |
POST /api/customer-account/auth/exchange, then /api/customer-account/* with the same JWT pattern |
Yes |
Headless detail that matters for SEO and security: v1 headless exchange is server-to-server. Your storefront backend calls SaveLayer with the Customer Account API token; SaveLayer resolves the customer and mints a SaveLayer JWT. Operation routes do not treat body fields as proof of identity. That is a better fit for Hydrogen wishlist and shopify headless wishlist than “paste a Storefront customer token into the browser and hope.”
Customer Account API vs “Storefront API wishlist”: it is normal to build product discovery with the Storefront API and still need a dedicated save API. SaveLayer’s headless path is explicitly Customer Account API–backed at exchange time so who is saving is anchored to Shopify’s account system, not a loose client claim.
One mental model: SDK on the theme, direct API where you own the server
- Themes: developers integrate via the theme extension and app proxy; shoppers interact through
window.SaveLayerwhere we expose it. - Headless and extensions: you call the documented REST-style routes under
/api/headless/*and/api/customer-account/*after exchange, with shared response envelopes from@savelayer/contracts.
So it is one product contract and one dispatcher, with ingress and auth matched to each channel. That is what we mean by unified save API without pretending every surface ships the same npm import.
Plan and channel entitlements still apply (for example, headless and customer-account routes are plan-gated separately from Online Store proxy traffic). Confirm current limits in Pricing and Authorization.
How this pairs with native data ownership
If metaobjects and merchant-owned saves are part of your evaluation, read Native wishlist on Shopify. For buyer-oriented checklist copy, start with Choosing a Shopify wishlist app.
Implementation: Documentation, Theme integration, API reference. Questions: Contact us.