Shopify Storefront API Learning Kit

repository·main·Indexed 19 days ago

https://github.com/shopify/storefront-api-learning-kit

A learning resource providing example GraphQL queries and an Insomnia collection to help developers build custom, headless commerce experiences using Shopify's Storefront API. Includes guides on configuring environment variables, managing metafields and metaobjects, handling international pricing and localization via the @inContext directive, and querying product pickup availability.

Tokens
16.8K
Snippets
47
Records
49
Agent score
16%

What's inside shopify-storefront-api-learning-kit

  1. Install the Headless channel to enable Storefront API access

    main

    To use the Storefront API, you must enable access by installing the Headless channel on your Shopify store. You can install it via the Shopify App Store or directly from your Shopify Admin:

    1. From your Shopify admin, click Sales channels.
    2. Click Recommended sales channels.
    3. In the Picked for you modal, scroll to the Build custom storefronts section.
    4. Within the Headless: Build your own commerce stack card, click Add.
    5. Click Add sales channel.
    6. Click Create storefront.
  2. Retrieve metaobjects via Storefront API

    main

    Metaobjects are custom data structures. To access them via the Storefront API:

    1. Create a metaobject definition via Admin API using metaobjectDefinitionCreate.
    2. Set the access property for storefront to PUBLIC_READ in the definition.
    3. Create the metaobject using metaobjectCreate via Admin API.

    Once configured, you can query them using the Storefront API by type or by a specific id or handle.

    # List metaobjects by type
    query getMetaObjects(
      $type: String!,
      $sortKey: String,
      $first: Int,
      $reverse: Boolean
    ){
      metaobjects(
        type: $type,
        sortKey: $sortKey,
        first: $first,
        reverse: $reverse
      ) {
        edges {
          node {
            id
            fields {
              key
              value
            }
            handle
            updatedAt
            type
          }
        }
      }
    }
    
    # Retrieve a single metaobject
    query getMetaObject($id: ID!) {
      metaobject(id: $id) {
        id
        type
        updatedAt
        handle
        fields {
          key
          value
          type
        }
      }
    }
    
    # Variables for list
    {
      "type": "Product_Highlights",
      "sortKey": "id",
      "first": 10,
      "reverse": true
    }
  3. Import the Insomnia collection for Storefront API queries

    main

    The repository provides an Insomnia collection package that contains a complete set of sample GraphQL queries. Using this in the Insomnia HTTP client allows you to leverage automatic schema fetching and autocomplete.

    To use the collection:

    1. Download the latest collection file: builds/storefront-api-learning-kit-insomnia.json.
    2. Open the Insomnia Dashboard.
    3. Click Create, then click File.
    4. Select the downloaded JSON file.
    builds/storefront-api-learning-kit-insomnia.json
  4. Handle international pricing and localization

    main

    To support local currencies and languages, use the @inContext(country: $country) directive in your Storefront API queries. This allows you to retrieve localized data based on the user's country context.

    • Available Countries/Currencies: Query localization to see available languages, countries, and their respective currencies/unit systems.
    • Product Prices: When querying products with a country context, the price field returns the active local currency.
    • Price Ranges: Use priceRange and compareAtPriceRange to get min/max variant prices in the local currency.
    • Customer Orders: When querying orders for a customer, note that totalPrice returns the store's default currency, while variant prices within line items return the active local currency.
    # Get available countries and currencies
    query getCountriesAndCurrencies($country: CountryCode) @inContext(country: $country) {
      localization {
        language {
          isoCode
          name
        }
        availableCountries {
          currency {
            isoCode
            name
            symbol
          }
          isoCode
          name
          unitSystem
        }
        country {
          currency {
            isoCode
            name
            symbol
          }
          isoCode
          name
          unitSystem
        }
      }
    }
    
    # Get product prices in local currency
    query allProducts($country: CountryCode) @inContext(country: $country) {
      products(first: 1) {
        edges {
          node {
            title
            variants(first:1) {
              edges {
                node {
                  title
                  price {
                    amount
                    currencyCode
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # Get price ranges in local currency
    query getProductPriceRanges($country: CountryCode) @inContext(country: $country) {
      products(first: 1) {
        edges {
          node {
            title
            priceRange {
              minVariantPrice {
                amount
                currencyCode
              }
              maxVariantPrice {
                amount
                currencyCode
              }
            }
          }
        }
      }
    }
    
    # Get customer orders
    query getcustomerOrders($customerAccessToken: String!, $country: CountryCode) @inContext(country: $country) {
      customer(customerAccessToken: $customerAccessToken) {
        orders(first:10) {
          edges {
            node {
              totalPrice {
                amount
                currencyCode
              }
              lineItems(first:10) {
                edges {
                  node {
                    variant {
                      price {
                        amount
                        currencyCode
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  5. Expose metafields to the Storefront API

    main

    By default, metafields are only accessible via the Admin API. To make them available to the Storefront API, you must explicitly grant visibility using the Admin API's metafieldStorefrontVisibilityCreate mutation. This requires valid Admin API credentials.

    Common resource owners for metafields include Products, Collections, Customers, Blogs, Pages, Shop, and more.

    mutation createMetafieldStorefrontVisibility(
      $input: MetafieldStorefrontVisibilityInput!
    ) {
      metafieldStorefrontVisibilityCreate(input: $input) {
        metafieldStorefrontVisibility {
          id
          key
          ownerType
          namespace
          updatedAt
        }
        userErrors {
          field
          message
        }
      }
    }
    
    # Variables
    {
      "input": {
        "key": "drying_instructions",
        "namespace": "garment_care",
        "ownerType": "COLLECTION"
      }
    }
  6. Create a customer access token

    main

    To access customer-specific data (addresses, orders, metafields), you must first obtain a customerAccessToken. This is done via the customerAccessTokenCreate mutation by exchanging a user's email and password.

    mutation customerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) {
      customerAccessTokenCreate(input: $input) {
        customerAccessToken {
          accessToken
          expiresAt
        }
        customerUserErrors {
          code
          field
          message
        }
      }
    }
    
    # Variables
    {
      "input": {
        "email": "user@example.com",
        "password": "HiZqFuDvDdQ7"
      }
    }
  7. Configure environment variables for Storefront API requests

    main

    To interact with the Storefront API, you need to configure three specific environment variables used to construct requests:

    VariableDescription
    base_urlThe Shopify store domain (e.g., mydevstore.myshopify.com).
    api_versionThe Storefront API version used for requests (e.g., a specific version or unstable).
    storefront_access_tokenThe Public access token associated with your created Storefront. This is used to populate the X-Shopify-Storefront-Access-Token request header.
  8. Get product by handle or ID

    main

    Retrieve a single product. You can use the handle argument for a slug-based lookup or replace it with the id argument for a direct ID lookup.

    query getProductByHandle {
      product(handle: "my-test-product") {
        id
        title
        description
        variants(first: 3) {
          edges {
            cursor
            node {
              id
              title
              quantityAvailable
              price {
                amount
                currencyCode
              }
            }
          }
        }
      }
    }
  9. Get products in a collection

    main

    Retrieve products belonging to a specific collection identified by its handle.

    Key Features:

    • Pagination: The products connection requires pagination.
    • Sorting: Use the sortKey argument (e.g., BEST_SELLING) to order products.
    • Price Ranges: The query can return priceRange (min/max variant prices) for the product.
    • Images: The images connection can be used to fetch product thumbnails.
    query getProductsInCollection($handle: String!) {
      collection(handle: $handle) {
        id
        title
        products(first: 50, sortKey: BEST_SELLING) {
          edges {
            node {
              id
              title
              vendor
              availableForSale
              images(first: 1) {
                edges {
                  node {
                    id
                    url
                    width
                    height
                    altText
                  }
                }
              }
              priceRange {
                minVariantPrice {
                  amount
                  currencyCode
                }
                maxVariantPrice {
                  amount
                  currencyCode
                }
              }
            }
          }
        }
      }
    }
  10. Get blog by handle

    main

    A blog is a collection of articles (blog posts) published to the online store channel, typically used for magazines or newsletters. Use the getBlogByHandle query with a $handle string to fetch a specific blog and its associated articles.

    query getBlogByHandle($handle: String!) {
      blog(handle: $handle) {
        id
        title
        articles(first: 5) {
          edges {
            node {
              id
              title
            }
          }
        }
      }
    }

    Variables:

    {
      "handle": "my-blog"
    }