Back to Blog
ShopifyChrome ExtensionsJSON

How to Export Public Shopify Products to JSON

Download normalized products with nested variants and image links, preserve literal identifiers, and keep the capture manifest beside the JSON.

Anas Nadeem
4 min read

To export public Shopify products to JSON with Shopify Detector & Spy, capture the supported store, collection or product, download the catalog ZIP, and extract observed-catalog.json. It contains normalized product records with nested variants and image links. No Shopify Admin account is required for this public-source workflow.

If your next step is code, a nested product record can be easier to inspect than reconstructing product relationships from spreadsheet rows. The useful file still needs its source scope and capture status beside it.

I build Shopify Detector & Spy. This guide covers the browser workflow and the checks I would make before feeding its JSON into another system.

Capture a small public scope first

  1. Install the Chrome extension and open the public storefront you want to review.
  2. Click the extension while that storefront tab is active.
  3. Choose Whole website, Current collection, Current product, or another discovered collection where available.
  4. Select Get data and keep the popup open while collection runs.
  5. Preview a few products, then choose Download catalog ZIP.
  6. Extract observed-catalog.json and retain manifest.json with it.

The store listing checked on 1 November 2026 shows version 1.0.3, with JSON available in the ZIP. The version 1.0.4 source build also adds a separate Download JSON button. If your installed build has that button, its file contains the same captured product array as the ZIP's JSON. The ZIP remains the route when you also need the full manifest and companion files.

Understand the product and variant structure

The JSON is normalized observed catalog data, rather than an untouched server-response archive. Products retain their identities, titles, tags, image references and nested variants. Product IDs, variant IDs and source prices remain strings.

This shortened example uses fictional values and current extension field names; other fields are omitted:

[
  {
    "id": "9007199254740993",
    "title": "Example Rain Jacket",
    "tags": ["Rainwear"],
    "images": ["https://example.com/jacket.jpg"],
    "variants": [
      {
        "id": "9007199254740994",
        "title": "Small",
        "sku": "00042-S",
        "price": "29.90",
        "availability": "available"
      },
      {
        "id": "9007199254740995",
        "title": "Medium",
        "sku": "",
        "price": "29.90",
        "availability": "unknown"
      }
    ]
  }
]

That is one product and two variants. The empty SKU does not justify deleting the second variant. The observed availability value also does not establish actual inventory quantity.

Parse without changing source identities

For a small local inspection in Node.js, keep the original strings while creating a working view:

import { readFile } from "node:fs/promises";

const products = JSON.parse(
  await readFile("observed-catalog.json", "utf8")
);
const variants = products.flatMap((product) =>
  product.variants.map((variant) => ({
    productId: product.id,
    variantId: variant.id,
    sku: variant.sku,
    price: variant.price
  }))
);

console.log({ products: products.length, variants: variants.length });

Do not coerce long IDs into JavaScript numbers or deduplicate variants by SKU alone. Create your own numeric calculation fields separately when arithmetic is needed, retaining the source price and its currency evidence.

Read the manifest before using missing records

Keep the requested URL, selected scope, observation time and capture status. A successful download can still represent a partial capture. Missing records in that file do not automatically establish product removals.

Free includes 100 captured products per UTC calendar month in the browser profile. Pro removes the monthly product quota and has no fixed product or variant cap per run. Browser memory, storage and public-source access still affect the result.

Review image links as references, preserve missing fields as unknown, and inspect currency evidence before comparing prices. The export acceptance checklist provides a fuller file review.

Choose the interface for the next job

For one storefront in front of you, use the browser capture and keep its original ZIP. If you need supplied URL lists, API calls or saved tasks, use the separate Shopify Apify workflow, which has its own settings and billing.

If detection is unclear, start with how to tell whether a store uses Shopify. Then capture one relevant collection and trace one product and its variants through the JSON before expanding the job.