Headless and custom storefronts do not use a Shopify theme, so they cannot use the Wishlist app embed. The Wishlist SDK is a small JavaScript library that reads and writes the same saved-item lists the Tapcart app uses. Load the SDK, connect it to your customer login, then call its methods from your own heart buttons and wishlist page.
Wishlist is logged-in only. The web option is the Wishlist v2: account-keyed lists toggle in the Mobile Wishlist integration. When that is on, the shopper's web and in-app lists are the same list, tied to their Shopify customer account.
If you use a Shopify theme instead of a headless storefront, skip this SDK and follow Syncing Wishlist Across Web and App.
What the SDK does
The SDK is the data layer only. It does not render hearts, a wishlist page, or add-to-cart. Your storefront owns that UI.
What Tapcart provides: create and manage lists, add and remove items, and keep those lists in sync with the app for the same logged-in customer.
What you build: heart buttons on product cards and product pages, filled/unfilled state, a page to view and manage saved items, and add-to-cart from that list if you want it.
Save a product on your site, and it appears in the app. Save in the app, and it appears on your site the next time you load the shopper's lists.
Before you start
Connect Mobile Wishlist under Integrations in the Tapcart dashboard.
Your app must be on Tapcart React Native release 21.8.0 or newer. If you are unsure, contact your AM or LiveChat.
Have your Tapcart App ID ready.
Open the Tapcart dashboard
Click the shop name (top right) → Settings
In App Settings, scroll to the Tapcart CLI / Application ID section
Copy the App ID
Set up Wishlist Sync
Turn on Wishlist v2 and allowlist your origins
Both settings live on the same Mobile Wishlist integration page in the Tapcart dashboard.
Go to Integrations → Mobile Wishlist.
Turn on Wishlist v2: account-keyed lists (required for web and mobile wishlist sync).
Add your storefront origin(s) under Allowed Web Origins (headless).
Select Update Integration.
Use a bare origin only: scheme + host + optional port, with no path. Example: https://shop.example.com
Include staging origins if you will test there. Leave Allowed Web Origins empty unless you run a custom or headless storefront. Allowlist changes typically apply within a minute.
Load the SDK
<script src="https://api.tapcart.com/wishlist/sdk/v1/wishlist-sdk.js"></script>
The script defines TapcartWishlist. Nothing runs until you call init.
Initialize
const wishlist = TapcartWishlist.init({
appId: '<your Tapcart App ID>',
getCustomerToken: async () => myAuth.getShopifyCustomerToken(),
})getCustomerToken should return the logged-in shopper's Shopify customer token, or null for guests:
Customer Account API: the
shcat_tokenClassic customer accounts: the Storefront API
customerAccessToken
The SDK calls this helper on every method. Cache the token for the session instead of requesting a new one on every heart tap. After login, call a method such as getWishlists() so the helper can return the new token. There is no separate refresh method.
Enablement checklist
Turn on Wishlist v2 and add production and staging origins on the Mobile Wishlist integration page, then select Update Integration.
Add the script and
initon your site, with agetCustomerTokenhelper that returns the Shopify customer token.Wire your UI to
getWishlists,createWishlist,addItem, andremoveItem.Verify by logging in, saving an item on web, and confirming it appears in the app (and the reverse).
Utilizing the SDK
Read and update lists
Call these methods from your UI. Every method returns null (and makes no request) when the shopper is logged out. Treat null as "not logged in," not as an error.
const result = await wishlist.getWishlists()
let list = result && result.data && result.data[0]if (!list) {
list = await wishlist.createWishlist()
}const listId = list._id || list.idawait wishlist.addItem(listId, {
productId: '1234567890',
variantId: '9876543210',
})const updated = await wishlist.getWishlist(listId)
const item = updated.items.find((i) => i.productId === '1234567890')
if (item) {
await wishlist.removeItem(listId, item._id)
}getWishlists() returns { data, pagination }, or null if the shopper is logged out. createWishlist() with no name bootstraps the default list (usually "My Wishlist") so web and app share one list. Use numeric Shopify product and variant IDs (no gid://shopify/... prefix). The app stores the same numeric IDs. If web saves a GID and the app saves a number, the shopper will see duplicate items. To remove an item, use its _id from the list, not the product id.
SDK methods
getWishlists({ page, limit }): all of the customer's lists. Optional pagination (default page 1, default limit 10, max 100). Response shape:{ data, pagination }.createWishlist(name?): create a list. Omitnameto bootstrap the default list. Creating the same name twice returns the existing list.getWishlist(wishlistId): one list, including its items.renameWishlist(wishlistId, name): rename a list.deleteWishlist(wishlistId): delete a list.addItem(wishlistId, item): add an item. If it is already in the list, the call fails with status409.updateItem(wishlistId, itemId, patch): update an item (for example, change the variant).removeItem(wishlistId, itemId): remove an item by its item_id.
Use the list's _id (or id) for list methods. Use each item's _id for updateItem and removeItem.
Item payload
Pass at least one of productId, variantId, collectionId, or brandId. For products, pass both product and variant:
{ productId: '1234567890', variantId: '9876543210' }collectionId, brandId, and recurrence are optional. A heart toggle typically loads the list, checks whether that productId is already saved, then calls addItem or removeItem.
Guests
Headless Wishlist is logged-in only. When getCustomerToken returns null, every method resolves to null and no request is made. If you want guests to save items on your site, store those items in your own storage and add them with the SDK after login.
How it Works
Identity
Logged-in customers only. Each SDK call sends the Shopify customer token. Tapcart verifies it with Shopify and keys the list to that customer, so the same lists appear in the app.
Same list as the app
With Wishlist v2 enabled, web and app use the same wishlist tied to the shopper's Shopify customer account. Lists that lived only on the device are not visible on web, and they do not migrate automatically when you turn on Wishlist v2.
Using Cart Sync and Wishlist together
If you want both features on the same headless storefront:
Allowlist the origin in both places: Cart Sync settings and Mobile Wishlist.
Load both SDKs and initialize each with your App ID and customer token helper.
For Cart Sync setup, see Cart Sync for Headless Storefronts.
Troubleshooting
Forbidden origin errors
Confirm the exact bare origin is listed under Mobile Wishlist Allowed Web Origins, then retry after about a minute.
SDK calls return nothing / no lists
Confirm the shopper is logged in and getCustomerToken returns a valid token. Also confirm Wishlist v2 is enabled so lists are tied to the Shopify customer ID.
Add fails with 409
The item is already in that list. For a heart button, treat 409 as "already saved" and show the filled state.
Items appear twice (web vs app)
Web and app must save the same ID format. Use numeric Shopify product and variant IDs, not GraphQL GIDs.
Rate limit responses
Token verification is rate limited (HTTP 429). This is uncommon in normal use. Cache the customer token for the session instead of requesting a new one on every wishlist action.
More Questions
Need help with a headless Wishlist integration? Reach out through LiveChat on your Tapcart Dashboard or email us at [email protected].

