Shopify storefront API for WooCommerce developers (2026)
How WooCommerce developers use the Shopify Storefront API — GraphQL basics, cart management, product queries, customer authentication, and building headless or custom storefront features after migration.
WooCommerce developers extending their stores with custom JavaScript (jQuery, vanilla JS, React) used WooCommerce's AJAX actions, REST API, and WordPress hooks. On Shopify, the equivalent client-side development uses the Storefront API — a public-facing GraphQL API for product queries, cart management, and customer operations. This guide introduces the Storefront API for developers familiar with WooCommerce's approach.
WooCommerce frontend APIs vs Shopify
| Use case | WooCommerce | Shopify |
|---|---|---|
| Query products client-side | WC REST API v3 or WP_Query via AJAX | Storefront API: productQuery, products |
| Cart management | WC AJAX add-to-cart + wc_add_to_cart_params | Storefront API: cartCreate, cartLinesAdd, cartLinesUpdate |
| Customer login | WP authentication | Storefront API: customerAccessTokenCreate |
| Customer account data | WP user meta, WC customer API | Storefront API: customer query |
| Search products | WP_Query search or SearchWP | Storefront API: predictiveSearch, search |
| Dynamic section updates | WordPress AJAX + PHP partial render | Shopify Section Rendering API |
| Metafield reading | WP postmeta via AJAX | Storefront API: product.metafields |
Storefront API basics
Authentication
The Storefront API uses a public Storefront Access Token (not the Admin API key). Create one in Admin → Apps → Develop apps → create a custom app → enable Storefront API access:
// Storefront API endpoint
const SHOPIFY_DOMAIN = 'yourstore.myshopify.com';
const STOREFRONT_TOKEN = 'your_storefront_access_token';
const endpoint = 'https://' + SHOPIFY_DOMAIN + '/api/2024-01/graphql.json';
async function storefrontQuery(query, variables = {}) {
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': STOREFRONT_TOKEN,
},
body: JSON.stringify({ query, variables }),
});
return response.json();
}
Product queries
Fetch product by handle
const PRODUCT_QUERY = `
query getProduct($handle: String!) {
product(handle: $handle) {
id
title
description
priceRange {
minVariantPrice { amount currencyCode }
maxVariantPrice { amount currencyCode }
}
variants(first: 100) {
edges {
node {
id
title
price { amount currencyCode }
availableForSale
selectedOptions { name value }
sku
}
}
}
images(first: 10) {
edges {
node { url altText width height }
}
}
}
}
`;
const result = await storefrontQuery(PRODUCT_QUERY, { handle: 'my-product' });
Fetch product metafields
const PRODUCT_METAFIELDS_QUERY = `
query getProductWithMetafields($handle: String!) {
product(handle: $handle) {
title
metafield(namespace: "product_info", key: "material") {
value
type
}
metafields(identifiers: [
{ namespace: "product_info", key: "material" },
{ namespace: "product_info", key: "weight_g" }
]) {
namespace
key
value
type
}
}
}
`;
Note: metafields must be set to "storefront accessible" in Admin → Settings → Custom data to be readable via Storefront API.
Cart management (replaces WooCommerce AJAX cart)
Create a cart
const CREATE_CART = `
mutation cartCreate($input: CartInput!) {
cartCreate(input: $input) {
cart {
id
checkoutUrl
lines(first: 10) {
edges {
node {
id
quantity
merchandise {
... on ProductVariant {
id title price { amount }
}
}
}
}
}
cost {
totalAmount { amount currencyCode }
}
}
userErrors { field message }
}
}
`;
const result = await storefrontQuery(CREATE_CART, {
input: {
lines: [{ quantity: 1, merchandiseId: 'gid://shopify/ProductVariant/12345' }],
buyerIdentity: { email: 'customer@example.com' }
}
});
const cartId = result.data.cartCreate.cart.id;
// Store cartId in localStorage for cart persistence
Add to cart (WooCommerce wc_add_to_cart equivalent)
const ADD_TO_CART = `
mutation cartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) {
cartLinesAdd(cartId: $cartId, lines: $lines) {
cart {
id
lines(first: 20) {
edges {
node {
id quantity
merchandise {
... on ProductVariant { id title }
}
}
}
}
cost { totalAmount { amount currencyCode } }
}
userErrors { field message }
}
}
`;
await storefrontQuery(ADD_TO_CART, {
cartId: 'gid://shopify/Cart/abc123',
lines: [{ quantity: 2, merchandiseId: 'gid://shopify/ProductVariant/67890' }]
});
Customer authentication
WooCommerce used WordPress cookies for customer sessions. Shopify Storefront API uses access tokens:
// Login (get customer access token)
const CUSTOMER_LOGIN = `
mutation customerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) {
customerAccessTokenCreate(input: $input) {
customerAccessToken {
accessToken
expiresAt
}
customerUserErrors { code field message }
}
}
`;
const loginResult = await storefrontQuery(CUSTOMER_LOGIN, {
input: { email: 'customer@example.com', password: 'password' }
});
const accessToken = loginResult.data.customerAccessTokenCreate.customerAccessToken.accessToken;
// Fetch customer data with access token
const CUSTOMER_QUERY = `
query getCustomer($customerAccessToken: String!) {
customer(customerAccessToken: $customerAccessToken) {
id
firstName lastName email
orders(first: 5) {
edges {
node {
id orderNumber totalPriceV2 { amount currencyCode }
processedAt
}
}
}
}
}
`;
Predictive search (WooCommerce live search equivalent)
const PREDICTIVE_SEARCH = `
query predictiveSearch($query: String!) {
predictiveSearch(query: $query) {
products {
id title handle
featuredImage { url altText }
priceRange { minVariantPrice { amount currencyCode } }
}
collections { id title handle }
pages { id title handle }
}
}
`;
// Debounced search input handler
async function handleSearchInput(query) {
if (query.length < 3) return;
const results = await storefrontQuery(PREDICTIVE_SEARCH, { query });
renderSearchResults(results.data.predictiveSearch.products);
}
Section Rendering API (WooCommerce AJAX partial render equivalent)
Shopify's Section Rendering API renders theme sections server-side and returns HTML — the Shopify equivalent of WordPress AJAX partial renders:
// Render cart drawer section via Section Rendering API
async function refreshCartDrawer() {
const response = await fetch('/cart?sections=cart-drawer');
const data = await response.json();
document.getElementById('cart-drawer').innerHTML = data['cart-drawer'];
}
// Render product form after variant switch
async function renderProductForm(productHandle, variantId) {
const response = await fetch(
`/products/${productHandle}?variant=${variantId}§ions=product-form`
);
const data = await response.json();
document.getElementById('product-form').innerHTML = data['product-form'];
}
Key differences from WooCommerce AJAX
- No nonces required: Shopify Storefront API and Section Rendering API don't require WordPress security nonces
- GraphQL not REST: Storefront API is GraphQL — request exactly the fields you need. No over-fetching.
- Storefront access token is public: Unlike Admin API, Storefront token is safe to expose in client-side JavaScript
- No server-side session: Cart is identified by cart ID (stored in localStorage/cookie). No server-side WooCommerce session needed.
- Checkout is Shopify-hosted: The
cart.checkoutUrlredirects to Shopify's hosted checkout — no custom PHP checkout page - No WP_Query: Can't query products with arbitrary WHERE conditions client-side. Use collections and search for product discovery.
Developer migration checklist
- Create a Storefront API access token: Admin → Apps → Develop apps → Storefront API permissions
- Enable metafield storefront access for all metafields needed in client-side JS
- Port any WooCommerce AJAX product queries to Storefront API GraphQL queries
- Replace WC AJAX add-to-cart with Storefront API cartLinesAdd mutations
- Store cart ID in localStorage; persist across page navigation
- Replace WooCommerce live search with Storefront API predictiveSearch
- Replace AJAX partial renders with Section Rendering API calls
- Replace WP customer authentication with Storefront API customerAccessTokenCreate
- Test all client-side cart and product features end-to-end on Shopify development store
The Section Rendering API is one of Shopify's most underused developer tools. It eliminates almost all cases where WooCommerce developers defaulted to AJAX + PHP partial renders — instead of writing a custom PHP endpoint to return cart HTML, call /cart?sections=cart-drawer and get the complete rendered HTML from the actual theme section. This approach keeps the cart rendering consistent with the theme, handles edge cases (discounts, gift cards, shipping estimates) automatically, and requires zero custom PHP equivalent code.
Migrate your store with k-sync
Connect your WooCommerce store, validate your products, and push to Shopify in minutes. Free for up to 50 products.
Get started freeRelated reading
Migrating a luggage and travel accessories store from WooCommerce to Shopify (2026)
How to migrate a luggage, travel bags, or travel accessories WooCommerce store to Shopify — luggage specifications, airline compliance, TSA lock, warranty and durability claims, and luggage retail Shopify setup.
Migrating a motorcycle accessories store from WooCommerce to Shopify (2026)
How to migrate a motorcycle accessories, biker gear, or motorbike parts WooCommerce store to Shopify — helmet safety standards, CE-rated protective clothing, type approval for parts, fitment compatibility, and motorcycle retail Shopify setup.