Claude
Skills
Sign in
Back

shopify-storefront-api

Included with Lifetime
$97 forever

Build a headless Shopify frontend using the GraphQL Storefront API for product queries, cart management, and checkout with the Buy SDK

platform-shopifyshopifystorefront-apiheadlessgraphqlbuy-sdknext-jshydrogencart

What this skill does


# Shopify Storefront API

## Overview

The Shopify Storefront API is a public-facing GraphQL API that provides read and write access to a store's products, collections, cart, and checkout from any frontend. It uses a Storefront Access Token (distinct from Admin API tokens) and is safe to expose in client-side JavaScript. Use it to build headless storefronts with Next.js, Remix/Hydrogen, or any JS framework.

## When to Use This Skill

- When building a headless Shopify storefront with a custom frontend framework
- When creating a React Native or Flutter mobile app that needs product and cart data
- When embedding a Shopify buy button or product widget in a non-Shopify site
- When using Shopify Hydrogen (Remix-based) for a fully custom storefront experience
- When needing real-time product availability or pricing without the Admin API overhead
- When implementing cart persistence across sessions with Shopify's hosted cart

## Core Instructions

1. **Create a Storefront Access Token**

   In Shopify Admin → Apps → Develop apps → Your App → API credentials → Storefront API access token. Or via the Admin API:

   ```javascript
   // Via Admin API (one-time setup)
   const token = await admin.graphql(`
     mutation {
       storefrontAccessTokenCreate(input: { title: "Headless Frontend" }) {
         storefrontAccessToken {
           accessToken
           title
         }
         userErrors { field message }
       }
     }
   `);
   ```

   Storefront Access Tokens do not use the `shpat_` prefix (that prefix is for Admin API tokens). Storefront tokens are opaque strings safe to use in browser code — they only allow storefront-scoped operations.

2. **Set up the Storefront API client**

   Using the official `@shopify/storefront-api-client`:

   ```bash
   npm install @shopify/storefront-api-client
   ```

   ```typescript
   // lib/shopify.ts
   import { createStorefrontApiClient } from "@shopify/storefront-api-client";

   export const storefront = createStorefrontApiClient({
     storeDomain: process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN!, // e.g. "mystore.myshopify.com"
     apiVersion: "2025-01",
     publicAccessToken: process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_TOKEN!,
   });
   ```

   For server-side calls with a private access token (higher rate limits):

   ```typescript
   export const storefrontServer = createStorefrontApiClient({
     storeDomain: process.env.SHOPIFY_STORE_DOMAIN!,
     apiVersion: "2025-01",
     privateAccessToken: process.env.SHOPIFY_STOREFRONT_PRIVATE_TOKEN!,
   });
   ```

3. **Query products and collections**

   ```typescript
   // lib/products.ts
   export async function getProducts(first = 20, after?: string) {
     const { data, errors } = await storefront.request(`
       query GetProducts($first: Int!, $after: String) {
         products(first: $first, after: $after, sortKey: BEST_SELLING) {
           pageInfo {
             hasNextPage
             endCursor
           }
           edges {
             node {
               id
               title
               handle
               availableForSale
               priceRange {
                 minVariantPrice { amount currencyCode }
                 maxVariantPrice { amount currencyCode }
               }
               images(first: 1) {
                 edges {
                   node { url altText width height }
                 }
               }
               variants(first: 10) {
                 edges {
                   node {
                     id
                     title
                     availableForSale
                     selectedOptions { name value }
                     price { amount currencyCode }
                   }
                 }
               }
             }
           }
         }
       }
     `, { variables: { first, after } });

     if (errors) throw new Error(errors.message);
     return data.products;
   }
   ```

4. **Create and manage a cart**

   ```typescript
   // lib/cart.ts

   // Create a new cart
   export async function cartCreate(lines: { merchandiseId: string; quantity: number }[]) {
     const { data } = await storefront.request(`
       mutation CartCreate($lines: [CartLineInput!]) {
         cartCreate(input: { lines: $lines }) {
           cart {
             id
             checkoutUrl
             lines(first: 50) {
               edges {
                 node {
                   id
                   quantity
                   merchandise {
                     ... on ProductVariant {
                       id
                       title
                       price { amount currencyCode }
                       product { title handle }
                     }
                   }
                 }
               }
             }
             cost {
               subtotalAmount { amount currencyCode }
               totalAmount { amount currencyCode }
             }
           }
           userErrors { field message }
         }
       }
     `, { variables: { lines } });
     return data.cartCreate;
   }

   // Add lines to existing cart
   export async function cartLinesAdd(cartId: string, lines: { merchandiseId: string; quantity: number }[]) {
     const { data } = await storefront.request(`
       mutation CartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) {
         cartLinesAdd(cartId: $cartId, lines: $lines) {
           cart { id checkoutUrl }
           userErrors { field message }
         }
       }
     `, { variables: { cartId, lines } });
     return data.cartLinesAdd;
   }
   ```

5. **Persist cart ID and redirect to checkout**

   ```typescript
   // hooks/useCart.ts
   import { useState, useEffect } from "react";
   import { cartCreate, cartLinesAdd } from "../lib/cart";

   const CART_ID_KEY = "shopify_cart_id";

   export function useCart() {
     const [cartId, setCartId] = useState<string | null>(null);
     const [checkoutUrl, setCheckoutUrl] = useState<string | null>(null);

     useEffect(() => {
       setCartId(localStorage.getItem(CART_ID_KEY));
     }, []);

     const addToCart = async (variantId: string, quantity = 1) => {
       const lines = [{ merchandiseId: variantId, quantity }];
       if (cartId) {
         const result = await cartLinesAdd(cartId, lines);
         setCheckoutUrl(result.cart.checkoutUrl);
       } else {
         const result = await cartCreate(lines);
         const newCartId = result.cart.id;
         localStorage.setItem(CART_ID_KEY, newCartId);
         setCartId(newCartId);
         setCheckoutUrl(result.cart.checkoutUrl);
       }
     };

     const goToCheckout = () => {
       if (checkoutUrl) window.location.href = checkoutUrl;
     };

     return { addToCart, goToCheckout, cartId };
   }
   ```

## Examples

### Product Detail Page with variant selection (Next.js)

```typescript
// app/products/[handle]/page.tsx
import { storefront } from "@/lib/shopify";

async function getProduct(handle: string) {
  const { data } = await storefront.request(`
    query GetProduct($handle: String!) {
      product(handle: $handle) {
        id
        title
        descriptionHtml
        seo { title description }
        images(first: 10) {
          edges { node { url altText } }
        }
        options {
          id name values
        }
        variants(first: 100) {
          edges {
            node {
              id
              availableForSale
              selectedOptions { name value }
              price { amount currencyCode }
              compareAtPrice { amount currencyCode }
            }
          }
        }
      }
    }
  `, { variables: { handle } });
  return data.product;
}

export default async function ProductPage({ params }: { params: { handle: string } }) {
  const product = await getProduct(params.handle);
  // Render product with client-side variant picker
  return <ProductDetail product={product} />;
}

// Generate static params for all products
export async function generateStaticParams() {
  const {

Related in platform-shopify