Headless E-Commerce Integration: Connecting Shopify Storefront API with Next.js

ShipSaaS Team

In Part 1 of this series, we explored the key commercial and SEO opportunities offered by Shopify, including their active promotions. Now, it's time to roll up our sleeves and look at the actual code.

For developers seeking absolute control over their UI/UX, page speed, and marketing funnels, headless e-commerce is the gold standard.

By leveraging the Shopify Storefront API alongside a modern, speed-optimized Next.js boilerplate, you can build ultra-fast, customized shopping experiences while leaving complex order and inventory logistics to Shopify's backend.

In this guide, we will implement a clean, lightweight integration to fetch products from Shopify and render them dynamically in a Next.js page.


🛠️ Step 1: Generating Storefront API Credentials

Before writing React code, you need to generate API credentials inside your Shopify Admin dashboard:

  1. Log in to your Shopify Admin console.
  2. Go to Settings > App and sales channels > Develop apps.
  3. Click Create an app, name it (e.g., NextJS Headless Storefront), and select your developer account.
  4. Under the Configuration tab, select Storefront API integration and click Configure.
  5. Grant permissions for the resources you need (e.g., unauthenticated_read_product_listings, unauthenticated_read_checkout).
  6. Click Save and then click Install app at the top right.
  7. Under the API credentials tab, copy the Storefront API access token and your shop's domain (e.g., your-store-name.myshopify.com).

🔒 Step 2: Configuring Environment Variables

Add these keys to your Next.js .env file. If you are using our production-ready SaaS starter kit, these can be securely injected into your deployment setup:

NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN="your-store-name.myshopify.com"
NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN="your_storefront_access_token_here"

📡 Step 3: Creating a Unified Shopify Client

We will build a simple fetcher that handles GraphQL requests to Shopify's endpoints. Because Next.js uses powerful caching and data fetching mechanisms, we can make server-side components retrieve catalog data statically or dynamically with ease.

Create a helper file at src/lib/shopify.ts:

const domain = process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN;
const token = process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN;

export async function shopifyFetch<T>({
  query,
  variables = {},
}: {
  query: string;
  variables?: Record<string, any>;
}): Promise<{ status: number; body: T }> {
  try {
    const response = await fetch(`https://${domain}/api/2024-01/graphql.json`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Shopify-Storefront-Access-Token": token || "",
      },
      body: JSON.stringify({ query, variables }),
      next: { revalidate: 3600 }, // Cache products for 1 hour
    });

    return {
      status: response.status,
      body: await response.json(),
    };
  } catch (error) {
    console.error("Error fetching from Shopify:", error);
    throw error;
  }
}

📊 Step 4: Fetching and Rendering Products

Let’s write a GraphQL query to fetch the first six products from your Shopify inventory.

export interface ShopifyProduct {
  id: string;
  title: string;
  handle: string;
  description: string;
  images: {
    edges: Array<{
      node: {
        url: string;
        altText: string;
      };
    }>;
  };
  priceRange: {
    minVariantPrice: {
      amount: string;
      currencyCode: string;
    };
  };
}

interface ShopifyProductsResponse {
  data: {
    products: {
      edges: Array<{
        node: ShopifyProduct;
      }>;
    };
  };
}

export async function getProducts(): Promise<ShopifyProduct[]> {
  const query = `
    query GetProducts {
      products(first: 6) {
        edges {
          node {
            id
            title
            handle
            description
            images(first: 1) {
              edges {
                node {
                  url
                  altText
                }
              }
            }
            priceRange {
              minVariantPrice {
                amount
                currencyCode
              }
            }
          }
        }
      }
    }
  `;

  const res = await shopifyFetch<ShopifyProductsResponse>({ query });
  return res.body.data.products.edges.map((edge) => edge.node);
}

By retrieving this clean product array, you can instantly render high-performance, responsive CSS grids in your custom storefront page. It allows you to build a landing page that loads in under 100 milliseconds, giving you a massive advantage in SEO rankings.


⚡ The Ultimate Conversion Combo: Shopify + ShipSaaS

Many successful developers don't just sell physical products—they build sophisticated SaaS platforms with integrated retail components or e-commerce agencies.

For instance, they offer a subscription service (handled via our sleek Stripe subscription setup) that unlocks special discounts on custom physical goods powered by Shopify.

To orchestrate this, you need a robust, battle-tested system that includes:

  • Production-ready user authentication.
  • Seamless multi-language translation arrays out-of-the-box (using next-intl).
  • Edge-optimized database query systems.
  • Flexible pricing blocks to target enterprise users.

Instead of spending weeks setting up these infrastructure layers from scratch, you can deploy your entire tech stack in a single afternoon. Check out our highly flexible ShipSaaS pricing and start building immediately.


🏁 Next Steps

Now that you have connected the Storefront API, you can:

  1. Implement a headless shopping cart system.
  2. Direct users to the high-converting Shopify web checkout.
  3. Hook up webhooks to automatically provision platform features when an e-commerce order is paid.

Headless architecture represents the future of scalable commerce. Deploy it today to experience unmatched freedom in your SaaS design journey!