• Stars
    star
    171
  • Rank 222,266 (Top 5 %)
  • Language
    JavaScript
  • Created over 3 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Storefront API Learning Kit

About this repo | How to use this repo | Contribute to this repo | Getting started | Example queries

About this repo

This repo provides example queries demonstrating how to use Shopify's GraphQL Storefront API. Downloading the Storefront API insomnia collection package, gives you access to a complete set of sample queries for use in the Insomnia http client. The Insomnia desktop app comes with rich GraphQL features, including automatic schema fetching and autocomplete, which are extremely valuable in learning a new API.

How to use this repo

To import the Insomnia package, first download the latest collection (you'll need to save the raw JSON file). From the Insomnia Dashboard screen, click Create, followed by clicking File. Select the file you downloaded. If you don't want to download the Insomnia package, the query examples are listed out below.

Getting started

Introduction

This learning kit provides a set of common GraphQL queries and mutations used with the Shopify Storefront API.

If not already familiar with GraphQL, or Shopify APIs, please consult the Shopify GraphQL learning kit https://shopifypartnerblog.myshopify.com/blogs/blog/shopify-graphql-learning-kit

The Shopify Storefront API gives you full creative control to customize your customers' buying experience.

With the Storefront API you can access several Shopify resource types with the following access scopes:

  • Read products, variants, and collections.
  • Read and modify customer details.
  • Read and modify checkouts.
  • Read store content like articles, blogs and comments.
  • Read subscription selling plans.
  • Read and modify cart objects.

Unlike the Admin API, the Storefront API is an unauthenticated API. Any data exposed by the Storefront API can be seen by any visitor to the store. Only use the Storefront API when you're comfortable with that risk and the data that is being exposed. Risk can be mitigated by only providing access scopes required. For a complete list of access scopes consult Shopify documentation at https://shopify.dev/api/usage/access-scopes#unauthenticated-access-scopes

Access to the Storefront API can be granted by a merchant via a public sales channel, or by creating a Headless channel in your Shopify Admin. For simplicity of this tutorial, we'll create a Headless channel in the Shopify Admin. The process to add the Headless channel is documented in the next section titled "Installing the Headless Channel ".

Documentation for accessing the Storefront API using the Headless channel can be found here

The home of Storefront API-related developer documents and tutorials can be found at https://shopify.dev/api/storefront

Installing the headless channel

To start using the Storefront API you'll need to enable access by installing the Headless channel on your store. To install, you can follow the directions outlined here or get it from the Shopify App Store.

Installing the Headless Channel from 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.

Configure your environment variables

Environment variables are JSON key-value pairs that allow you to refer to values without having to write them out every time.

For the tutorial, three environment variables will be utilized.

  1. base_url will be the Shopify store being connected to.
  • If your store is mydevstore.myshopify.com, enter “mydevstore.myshopify.com” here.
  1. api_version is the Storefront API version used for the API requests.
  • This can be changed to an earlier version or unstable depending on your use case.
  1. storefront_access_token is used to populate the X-Shopify-Storefront-Access-Token request header.
  • This is the Public access token associated with the Storefront you created in the "Installing the Headless Channel" section.

Making your first request

You should see at the top of the frame that we're using the "base_url" and "api_version" to build out the address for the endpoint. You can also click the "Headers" tab at the top to see the "storefront_access_token" being used. Hovering over environment variables should show you the value that will be substituted into the request. If you don’t see your values, ensure you have the right environment selected.

Once you've confirmed these three fields are set in your environment, try running the shop query below. If the Storefront API access token has been configured correctly, you should get your shop’s info returned.

query getShopDetails{
  shop {
    name
    primaryDomain{
      host
      url
    }
    paymentSettings{
      currencyCode
      acceptedCardBrands
      enabledPresentmentCurrencies
    }
  }
}

Example queries

Metafields metaobjects

Expose metafield to SFAPI

Metafields allow merchants to store additional information for Shopify resources including:

  • Products
  • Collections
  • Customers
  • Blogs
  • Pages
  • Shop
  • Discounts
  • Draft Orders
  • Locations
  • Orders
  • Product Images
  • Product Variants

For a complete list please consult https://shopify.dev/api/admin-graphql/2022-10/enums/MetafieldOwnerType

Unlike the Admin API, metafields must first be made visible to the Storefront API. To make metafields visible to the Storefront API use the Shopify Admin API mutation metafieldStorefrontVisibilityCreate.

Ensure you are calling the Admin API https://shopify.dev/api/admin-graphql#endpoints with valid Admin API credentials https://shopify.dev/api/admin-graphql#authentication when exposing metafields to the Storefront API.

For more information on the metafieldStorefrontVisibilityCreate mutation consult the Shopify Admin API doc https://shopify.dev/docs/admin-api/graphql/reference/metafields/metafieldstorefrontvisibilitycreate

For a complete Storefront API metafield reference please consult the metafield tutorial at https://shopify.dev/tutorials/retrieve-metafields-with-storefront-api#expose-metafields-to-the-storefront-api

mutation createMetafieldStorefrontVisibility(
  $input: MetafieldStorefrontVisibilityInput!
) {
  metafieldStorefrontVisibilityCreate(input: $input) {
    metafieldStorefrontVisibility {
      id # MetafieldStorefrontVisibility record id
      key # Key must be unique within this namespace on this resource
      ownerType
      namespace
      updatedAt
    }
    userErrors {
      field
      message
    }
  }
}

variables
{
  "input": {
    "key": "drying_instructions",
    "namespace": "garment_care",
    "ownerType": "COLLECTION"
  }
}

Retrieve metafields

Once a metafield has been exposed it can be retrieved using the Storefront API. In order to retrieve a single metafield, specify the namespace and key arguments. To query for a list of metafields pass the identifiers argument again specifying namespace and key For more information please consult https://shopify.dev/custom-storefronts/products-collections/metafields#step-2-retrieve-metafields

The following example retrieves a specific metafield and a list of metafields that match the supplied namespace and key and collection id. Ensure that you've added a value to any metafields you wish to query back by updating it using Admin API https://shopify.dev/apps/metafields/manage-metafields#step-3-update-a-metafield

query getCollectionMetaField(
  $id: ID!
  $namespace: String!
  $key: String!
  $another_namespace: String!
  $another_key: String!
) {
  collection(id: $id) {
    metafield(namespace: $namespace, key: $key) {
      key
      namespace
      value
      id # metafield id
    }
  }
  
  collection(id: $id) {
    metafields(
      identifiers: [
        { namespace: $namespace, key: $key },
        { namespace: $another_namespace, key: $another_key }
      ]
    ) {
      key
      namespace
      value
      id # metafield id
    }
  }
}

variables
{
  "id": "gid://shopify/Collection/288378781858",
  "namespace": "garment_care",
  "key": "wash_temperature",
  "another_namespace": "bakery",
  "another_key": "ingredients-new"
}

Retrieve storefront visibilities

To retrieve a list of MetafieldStorefrontVisibility records use the metafieldStorefrontVisibilities query available on the Admin API and return a list of exposed metafield records.

Ensure you are calling the Admin API https://shopify.dev/api/admin-graphql#endpoints with valid Admin API credentials https://shopify.dev/api/admin-graphql#authentication when retrieving a list of MetafieldStorefrontVisibility records. For a complete reference please consult https://shopify.dev/api/admin-graphql/2022-10/queries/metafieldStorefrontVisibilities#top

query getMetafieldStorefrontVisibilities($first: Int!, $namespace: String!) {
  metafieldStorefrontVisibilities(first: $first, namespace: $namespace) {
    edges {
      node {
        id # Metafield visibility record id
        namespace
        key
        createdAt
      }
    }
  }
}

variables
{
  "first": 5,
  "namespace": "garment_care"
}

Delete storefront visibilities

If you no longer need to access a metafield with the Storefront API, you can hide it again by using the GraphQL Admin API to delete the MetafieldStorefrontVisibility record that you created. The metafieldStorefrontVisibilityDelete mutation requires the visibility record of the metafield you wish to hide from the Storefront API. The metafield will no longer be accessible through the Storefront API.

Ensure you are calling the Admin API https://shopify.dev/api/admin-graphql#endpoints with valid Admin API credentials https://shopify.dev/api/admin-graphql#authentication when deleting a MetafieldStorefrontVisibility record. For a complete reference please consult https://shopify.dev/api/admin-graphql/2022-10/mutations/metafieldStorefrontVisibilityDelete

mutation deleteMetafieldStorefrontVisibilities($id: ID!) {
  metafieldStorefrontVisibilityDelete(id: $id) {
    deletedMetafieldStorefrontVisibilityId # The visibility record of the metafield hidden from Storefront API
    
    userErrors {
      field
      message
    }
  }
}

variables
{
  "id": "gid://shopify/MetafieldStorefrontVisibility/1684242594"
}

Retrieve metaobjects

Metaobjects are custom data structures introduced with version 2023-01 that your app can define and create to store your app's information. Similar to metafields, they can be associated with a Shopify resource such as a product or a collection. However, they can also exist on their own. Metaobjects provide you with a way to create resources that Shopify doesn't offer out of the box.

In order to query metaobjects with the Storefront API you must first create a metaobject definition using the Admin API with the metaobjectDefinitionCreate mutation and create a corresponding metaobject using the Admin API mutation metaobjectCreate. For more information consult Shopify Admin API docs at https://shopify.dev/api/admin-graphql/2023-01/mutations/metaobjectDefinitionCreate and https://shopify.dev/api/admin-graphql/2023-01/mutations/metaobjectCreate

When creating a new metaobject definition to create new associated metaobjects that you want to access using Storefront API, be sure to set "access" for the "storefront" property to "PUBLIC_READ". For more information about the MetaObjectDefinitionCreateInput please see https://shopify.dev/api/admin-graphql/2023-01/mutations/metaobjectDefinitionCreate#field-metaobjectdefinitioncreateinput-access Ensure you are calling the Admin API https://shopify.dev/api/admin-graphql#endpoints with valid Admin API credentials https://shopify.dev/api/admin-graphql#authentication

The following example returns a list of the first ten metaobjects for a given type from the Storefront API. As well as type, which is a required argument, either first or last must be passed. Other optional arguments include reverse and sortKey which determines whether to sort the returned list by "id", "type", "updated_at", or "display_name". For more information consult Storefront API documentation at https://shopify.dev/api/storefront/2023-01/queries/metaobjects

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
      }
    }
  }
}

variables
{
  "type": "Product_Highlights",
  "sortKey": "id",
  "first": 10,
  "reverse": true
}

Retrieve metaobject

The following example retreives a single metaobject by a given metaobject id. For more information consult Storefront API documentation at https://shopify.dev/api/storefront/2023-01/queries/metaobject

query getMetaObject($id: ID!) { # A metaobject can be retrieved by handle or id
  metaobject(id: $id) {
    id
    type
    updatedAt
    handle
    
    fields {
      key
      value
      type
    }
    
    fields {
      key
      value
      type
    }
  }
}

variables
{
  "id": "gid://shopify/Metaobject/819214"
}


International pricing

Get available countries and currencies

To present pricing in local currency enable the market of the passed in country context within Markets. If the country is not enabled in Markets the currency of the active localized experience will be the store's default currency.

To present a localized language experience enable it from Markets. If an alternate language is not enabled for the passed in country context, the active language will be the store's default.

query getCountriesAndCurrencies($country: CountryCode) @inContext(country: $country) {
  localization {
    language{ #The language of the active localized experience.
      isoCode
      name
    }
    availableCountries {
      currency {
        isoCode
        name
        symbol
      }
      isoCode
      name
      unitSystem
    }
    country { #The currency of the active localized experience.
      currency {
        isoCode
        name
        symbol
      }
      isoCode
      name
      unitSystem
    }
  }
}

variables
{
  "country": "FR"
}

Get product prices

query allProducts($country: CountryCode) @inContext(country: $country) {
  products(first: 1) {
    edges {
      node {
        title
        variants(first:1) {
          edges {
            node {
              title
              price {
                amount
                currencyCode #active local currency
              }
            }
          }
        }
      }
    }
  }
}

variables
{
  "country": "CA"
}

Get price ranges for products

query getProductPriceRanges($country: CountryCode) @inContext(country: $country) {
  products(first: 1) {
    edges {
      node {
        title
        priceRange {
          minVariantPrice {
            amount
            currencyCode  #active local currency
          }
          maxVariantPrice {
            amount
            currencyCode
          }
        }
        compareAtPriceRange {
          minVariantPrice {
            amount
            currencyCode  #active local currency
          }
          maxVariantPrice {
            amount
            currencyCode
          }
        }
      }
    }
  }
}

variables
{
  "country": "CA"
}

Get customer orders

query getcustomerOrders($customerAccessToken: String!, $country: CountryCode)@inContext(country: $country) {
  customer(customerAccessToken: $customerAccessToken) {
    orders(first:10) {
      edges {
        node {
          totalPrice {
            amount
            currencyCode # store's currency
          }
          lineItems(first:10) {
            edges {
              node {
                originalTotalPrice {
                  amount
                  currencyCode # store's currency
                }
                variant {
                  price {
                    amount
                    currencyCode # active local currency
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

variables
{
  "customerAccessToken": "customerAccessToken",
  "country": "FR"
}

Create cart in local context

Generates a cart in the currency and language of the context passed in. Requires that the country passed be enabled in Markets and that the language passed in is enabled for that market.

mutation cartCreate($cartInput: CartInput!, $country: CountryCode, $language: LanguageCode)@inContext(country: $country, language: $language){
  cartCreate(input: $cartInput) {
    userErrors {
      code
      message
    }
    cart {
      id
      checkoutUrl #URL for cart in local currency and language passed in
      lines(first: 50) {
        edges {
          node {
            id
            merchandise {
              ... on ProductVariant {
                title
                product {
                  title
                }
                id
                quantityAvailable
              }
            }
          }
        }
      }
      cost {
        subtotalAmount {
          amount #active local currency
          currencyCode
        }
        totalAmount {
          amount #active local currency
          currencyCode
        }
      }
    }
  }
}

variables
{
  "cartInput": {
    "lines": [
      {
        "quantity": 3,
        "merchandiseId": "gid://shopify/ProductVariant/42485059584162"
      },
      {
        "quantity": 1,
        "merchandiseId": "gid://shopify/ProductVariant/42790980223138"
      }
    ]
    
  },
  "country": "US",
  "language": "ES"
}


Local pickup

Get pickup availability for variants

Before sending this request, please make sure your app has unauthenticated_read_product_pickup_locations scope, and store pick up has been enabled. For all the requirements please check this dev doc: https://shopify.dev/custom-storefronts/products-collections/local-pickup#requirements

You can also use "id" to replace "handle" as argument to query product.

query getStoreAvailability($handle: String! $name: String! $value:String!) {
  product(handle:$handle) {
    variantBySelectedOptions(selectedOptions: {name: $name, value: $value}) {
    storeAvailability(first: 1) {
      edges {
        node {
          available
          pickUpTime
          location {
            name
          }
        }
      }
    }
  }
}
}

variables
{
"handle": "Orange",
"name": "Weight",
"value": "2 lb"
}

Get nearest pickup locations

This query will return the first 5 shop locations that support in-store pickup. The near parameter is used to sort results based on proximity to the provided location. Results could also be sorted by city, location id, or location name by using CITY, ID, or NAME respectively as the sortKey.

query getNearestPickupLocations($location: GeoCoordinateInput!) {
  locations(near:$location, first: 5, sortKey: DISTANCE) {
    edges {
      node {
        id
        name
        address {
          formatted
        }
      }
    }
  }
}

variables
{
  "location": {
    "latitude": 45.4553,
    "longitude": -75.6973
  }
}

Get preferred pickup location availability

Before sending this request, please make sure your app has unauthenticated_read_product_pickup_locations scope.

This query will return in-store pickup locations that have the product stocked, sorted by proximity to a buyers preferred store pickup location. The buyer's preferred pickup location is passed as the preferredLocationId argument.

query getPreferredStoreAvailability ($preferredLocationId: ID, $handle: String!,$selectedOptions: [SelectedOptionInput!]!)@inContext(preferredLocationId: $preferredLocationId) {
  product(handle: $handle) {
    variantBySelectedOptions(selectedOptions: $selectedOptions) {
      storeAvailability(first: 1) {
        edges {
          node {
            available
            pickUpTime
            location {
              name
            }
          }
        }
      }
    }
  }
}

variables
{
  "preferredLocationId": "gid://shopify/Location/65607794710",
  "handle": "Orange",
  "selectedOptions": {
    "name": "Weight",
    "value": "1 lb"
  }
}


Collections

Get collections

Simple query to return the first 10 collections in the shop.

Since a shop can contain multiple collections, pagination is required.

query getCollections {
  collections(first: 10) {
    edges {
      cursor
      node {
        id
        handle
      }
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
    }
  }
}

Get collection by handle

Simple query to return details from a collection object by passing the collection.handle as an argument.

query getCollectionByHandle($handle: String!) {
  collection(handle: $handle) {
    id
    title
    description
  }
}

variables
{
  "handle": "all"
}

Get collection by id

Query that returns details from a collection object by passing the collection.id as an argument.

query getCollectionById($id: ID!) {
  collection(id: $id) {
    title
    description
    handle
  }
}

variables
{
  "id": "gid://shopify/Collection/1"
}

Get products in collection

This query returns data from a single collection, specified by the handle.

The data returned in the product connection can be used to display a page of products.

The products connection requires pagination in this query, since collections can contain a large number of products. This query includes the sortKey argument on the products connection, this returns products in the order specified by the sortKey

Products can contain multiple images, so the images connection requires pagination.

Since products can contain multiple variants, we've asked the products connection to return price ranges.

In this example we only want to display 1 image per product, so we're only asking for first:1

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 { # Returns range of prices for a product in the shop's currency.
            minVariantPrice {
              amount
              currencyCode
            }
            maxVariantPrice {
              amount
              currencyCode
            }
          }
        }
      }
    }
  }
}

variables
{
  "handle": "all"
}

Get all metafields for namespace in collection

Uses the collectionByHandle query to specify a collection by passing the handle.

Identifiers are used to identify the metafields associated with the resource matching the supplied list of namespaces and keys.

The metafields connection is using the namespace argument to return only metafields in a specific namespace.

Since collections can have a large number of metafields in a given namespace, pagination is required on the metafields connection.

By default, the Storefront API can't read metafields. To make specific metafields visible in the Storefront API, you need to create a MetafieldStorefrontVisibility record.

For more information please consult #https://shopify.dev/custom-storefronts/products-collections/metafields

query getCollectionMetafieldsByNamespace($handle: String! $namespace: String!) {
  collection(handle: $handle) {
    id
    metafields(identifiers: [{ namespace: $namespace, key: $key }]) {
    key
    namespace
    value
    id
  }
}
}

variables
{
"handle": "all",
"namespace": "global"
}

Filter products in collection

You can use the Storefront API to filter products in a collection using product filters.

This functionality lets you build a desired customer experience on a storefront, such as the ability to narrow down the search results that you display to customers.

Products in collections can be filtered by type, vendor, variant options, price, stock and metafield value.

Please note there are requirements to using product filters in collections here - https://shopify.dev/custom-storefronts/products-collections/filter-products#requirements

In the following example, products in the collection that have the "shoes" product type are returned.

Further examples of product filters can be found in the above documentation.

query getProductsOfProductTypeInCollection($handle: String!, $value: String!) {
  collection(handle: $handle) {
    handle
    products(first: 10, filters: { productType: $value }) {
    edges {
      node {
        handle
        productType
      }
    }
  }
}
}

variables
{
"handle": "filterable-collection",
"value": "shoes"
}


Products

Get 3 products and 3 variants

This query gets the products connection, which is available from the QueryRoot, and asks for the first 3 products. It selects edges, the node, and fields from each of the returned product objects. Since products also have a variants connection, we repeat a similar process to get information on the first 3 variants on each of those products.

query getProductsAndVariants {
  products(first: 3) {
    edges {
      cursor
      node {
        id
        title
        description
        handle
        variants(first: 3) {
          edges {
            cursor
            node {
              id
              title
              quantityAvailable
              price {
                amount
                currencyCode
              }
            }
          }
        }
      }
    }
  }
}

Get product by handle

This query gets a single product connection, available from the QueryRoot, that matches the handle "my-test-product". As only one product connection will be returned, we don't need to specify edges, node, or cursor. This query can also be used to get a product by id by replacing (handle: $handle) with (id: $id)

query getProductByHandle {
  product(handle: "my-test-product") {
    id
    title
    description
    variants(first: 3) {
      edges {
        cursor
        node {
          id
          title
          quantityAvailable
          price {
            amount
            currencyCode
          }
        }
      }
    }
  }
}

Get product recommendations

This query gets a single product connection, available from the QueryRoot, that matches the base64-encoded id of the product. As only one product connection will be returned, we don't need to specify edges, node, or cursor.

query getProductRecommendations {
  productRecommendations(productId: "gid://shopify/Product/123456789") {
    id
    title
    description
    variants(first: 3) {
      edges {
        cursor
        node {
          id
          title
          quantityAvailable
          price {
            amount
            currencyCode
          }
        }
      }
    }
  }
}

Get product selling plans

This query gets the first 30 products, the first 5 selling plan groups associated with them, and the first 5 selling plans within the groups. We use fragments to return the price adjustments for each selling plan.

query getProductSellingPlans {
  products(first: 30) {
    pageInfo {
      hasNextPage
      hasPreviousPage
    }
    edges {
      cursor
      node {
        id
        title
        sellingPlanGroups(first: 5) {
          pageInfo {
            hasNextPage
            hasPreviousPage
          }
          edges {
            cursor
            node {
              appName
              name
              options {
                name
                values
              }
              sellingPlans(first: 5) {
                pageInfo {
                  hasNextPage
                  hasPreviousPage
                }
                edges {
                  cursor
                  node {
                    id
                    description
                    recurringDeliveries
                    priceAdjustments {
                      adjustmentValue {
                        ... on SellingPlanPercentagePriceAdjustment {
                          adjustmentPercentage
                        }
                        ... on SellingPlanFixedAmountPriceAdjustment {
                          adjustmentAmount {
                            amount
                            currencyCode
                          }
                        }
                        ... on SellingPlanFixedPriceAdjustment {
                          price {
                            amount
                            currencyCode
                          }
                        }
                      }
                      orderCount
                    }
                    options {
                      name
                      value
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Get product media

This query gets 3 products and their media; we use a fragment here to specify the fields that we want to return for each possible media type. You cannot retrieve media for product variants with the Storefront API, only products. You cannot upload media, add media to a product, or delete media with the Storefront API, use the Admin API for these tasks. https://shopify.dev/tutorials/manage-product-media-with-admin-api#retrieve-product-media-by-using-the-storefront-api

query getProductMedia {
  products(first: 3) {
    edges {
      cursor
      node {
        id
        title
        description
        media(first: 10) {
          edges {
            node {
              mediaContentType
              alt
              ...mediaFieldsByType
            }
          }
        }
      }
    }
  }
}

fragment mediaFieldsByType on Media {
  ...on ExternalVideo {
    id
    host
    originUrl
  }
  ...on MediaImage {
    image {
      url
    }
  }
  ...on Model3d {
    sources {
      url
      mimeType
      format
      filesize
    }
  }
  ...on Video {
    sources {
      url
      mimeType
      format
      height
      width
    }
  }
}

Get product tags

Returns product tags. This query requires the unauthenticated_read_product_tags scope, more info can be found here: https://shopify.dev/api/usage/access-scopes

query getProductTags {
  productTags(first:10) {
    edges{
      node
    }
  }
}

Get product types

Returns product types. This query requires the unauthenticated_read_product_listings scope, more info can be found here: https://shopify.dev/api/usage/access-scopes

query getProductTypes {
  productTypes(first: 10) {
    edges{
      node
    }
  }
}


Customers

Create an access token

The Storefront API allows access to a customer’s addresses, orders and metafields. To access customers, an app must have unauthenticated_read_customers access scope.

To query a customer, a customerAccessToken is required. This is obtained via the customerAccessTokenCreate mutation which exchanges a user’s email address and password for an access token.

mutation customerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) {
  customerAccessTokenCreate(input: $input) {
    customerAccessToken {
      accessToken
      expiresAt
    }
    customerUserErrors {
      code
      field
      message
    }
  }
}

variables
{
  "input": {
    "email": "[email protected]",
    "password": "HiZqFuDvDdQ7"
  }
}

Get customer orders

To query a customer, a customerAccessToken is required. This is obtained via the customerAccessTokenCreate mutation which exchanges a user’s email address and password for an access token.

query getCustomerOrders($customerAccessToken: String!){
  customer(customerAccessToken: $customerAccessToken) {
    id
    orders(first:3) {
      edges {
        node {
          orderNumber
        }
      }
    }
  }
}

variables
{
  "customerAccessToken": "d794063da4e26c9b1a8d7b77bdfd6862"
}

Get customer metafields

To query a customer, a customerAccessToken is required. This is obtained via the customerAccessTokenCreate mutation which exchanges a user’s email address and password for an access token.

By default, the Storefront API can't read metafields. To make specific metafields visible in the Storefront API, you need to create a MetafieldStorefrontVisibility record. See metafields/expose_metafield_to_SFAPI query for more details: # https://github.com/Shopify/storefront-api-learning-kit/tree/main/examples/05_collections/05_get_all_metafields_for_namespace_in_collection

If you would like to know more regarding metafields, check out this dev doc #https://shopify.dev/tutorials/retrieve-metafields-with-storefront-api#expose-metafields-to-the-storefront-api

Identifiers are used to identify the metafields associated with the resource matching the supplied list of namespaces and keys.

To know more about metafields, please navigate to metafields directory of this repo to get more information.

query CustomerMetafields($customerAccessToken: String!, $identifiers: [HasMetafieldsIdentifier!]!){
  customer(customerAccessToken: $customerAccessToken) {
    id
    email
    metafields (identifiers:$identifiers) {
      id
      key
      value
      namespace
      type
    }
  }
}

variables
{
  "customerAccessToken": "7cd6d36137f41d57bb8e85ae0d178d60",
  "identifiers": [
    {
      "namespace": "Membership",
      "key": "VIP level"
    },
    {
      "namespace": "Membership",
      "key": "startDate"
    },
    {
      "namespace": "note",
      "key": "preference"
    }
  ]
}

Update customer

To query a customer, a customerAccessToken is required. This is obtained via the customerAccessTokenCreate mutation which exchanges a user’s email address and password for an access token.

mutation customerUpdate($customerAccessToken: String!, $customer: CustomerUpdateInput!) {
  customerUpdate(customerAccessToken: $customerAccessToken, customer: $customer) {
    customer {
      id
    }
    customerAccessToken {
      accessToken
      expiresAt
    }
    customerUserErrors {
      code
      field
      message
    }
  }
}

variables
{
  "customerAccessToken": "d794063da4e26c9b1a8d7b77bdfd6862",
  "customer": {
    "phone": "+61401425227"
  }
}

Create customer

This mutation will create a customer account with password for the customer to login.

mutation createCustomerAccount($input: CustomerCreateInput!) {
  customerCreate(input: $input) {
    customer {
      id
      email
      firstName
      lastName
      phone
    }
    customerUserErrors {
      code
      field
      message
    }
  }
}

variables
{
  "input": {
    "acceptsMarketing": true,
    "email": "[email protected]",
    "firstName": "John",
    "lastName": "Smith",
    "password": "qwerty12345",
    "phone": "+64213444048"
  }
}

Activate customer

Once a customer account is created, an email will be sent to the customer with the account activation url. This mutation will use the activationToken from the activation url to active the customer account. You can also use the activation url directly to activate the customer account. See customerActivateByUrl mutation https://shopify.dev/api/storefront/2023-01/mutations/customerActivateByUrl

mutation activateCustomerAccount($id: ID!, $input: CustomerActivateInput!) {
  customerActivate(id: $id, input: $input) {
    customer {
      id
      email
      firstName
      lastName
      phone
    }
    customerAccessToken {
      accessToken
      expiresAt
    }
    customerUserErrors {
      code
      field
      message
    }
  }
}

variables
{
  "id": "gid://shopify/Customer/5820694691862",
  "input": {
    "activationToken": "da48cbd301e7c31a9d5dca03fcf5cdb6-1671054502",
    "password": "qwerty12345"
  }
}

Recover customer

This mutation will send a email to customer to reset password of the customer account.

Note that this mutation is throttled by IP. if you are using authenticated access, you can pass a Shopify-Storefront-Buyer-IP header to enable the IP based throttling that will protect your app from any single user, such as a bot, consuming too much capacity.

mutation recoverCustomerAccount($email: String!) {
  customerRecover(email: $email) {
    customerUserErrors {
      code
      field
      message
    }
  }
}

variables
{
  "email":"[email protected]"
}

Reset customer

This mutation is used to reset the customer account password. After sending recoverCustomerAccount request, the customer will receive an email with an account recovery url for resetting customer account. This url will include the customer id and resetToken. You can also use the url directly to reset the customer account. See customerResetByUrl mutation https://shopify.dev/api/storefront/2022-10/mutations/customerResetByUrl

mutation resetCustomerAccount($id: ID!, $input: CustomerResetInput!) {
  customerReset(id: $id, input: $input) {
    customer {
      id
      email
      firstName
      lastName
      phone
    }
    customerAccessToken {
      accessToken
      expiresAt
    }
    customerUserErrors {
      code
      field
      message
    }
  }
}

variables
{
  "id": "gid://shopify/Customer/5820694691862",
  "input": {
    "password": "12345qwerty",
    "resetToken": "2279f05aebbb8319553e46f2b71c88c7-1671131136"
  }
}

Create customer address

To query a customer, a customerAccessToken is required. This is obtained via the customerAccessTokenCreate mutation which exchanges a user’s email address and password for an access token.

This request will create a new address that appends to the current address array of the customer record.

mutation customerAddressCreate($customerAccessToken: String!, $address: MailingAddressInput!) {
  customerAddressCreate(customerAccessToken: $customerAccessToken, address: $address) {
    customerUserErrors {
      code
      field
      message
    }
    customerAddress {
      id
    }
  }
}

variables
{
  "customerAccessToken": "7cd6d36137f41d57bb8e85ae0d178d60",
  "address": {
    "lastName": "Smith",
    "firstName": "Mary",
    "address1": "123 Test Street",
    "province": "ON",
    "country": "Canada",
    "zip": "M5T1G4",
    "city": "Toronto"
  }
}


Manage a cart

Create a cart with one line item

This mutation creates a cart and returns information about the cart to ensure it's correct (id, lines, product variant id, etc) as well as some information about the cart you may want (e.g. cost, subtotalAmount, totalTaxAmount, totalDutyAmount). The checkoutUrl object contains the url of the checkout for the created cart

mutation createCart($cartInput: CartInput) {
  cartCreate(input: $cartInput) {
    cart {
      id
      createdAt
      updatedAt
      checkoutUrl
      lines(first: 10) {
        edges {
          node {
            id
            merchandise {
              ... on ProductVariant {
                id
              }
            }
          }
        }
      }
      attributes {
        key
        value
      }
      cost {
        totalAmount {
          amount
          currencyCode
        }
        subtotalAmount {
          amount
          currencyCode
        }
        totalTaxAmount {
          amount
          currencyCode
        }
        totalDutyAmount {
          amount
          currencyCode
        }
      }
    }
  }
}

variables
{
  "cartInput": {
    "lines": [
      {
        "quantity": 1,
        "merchandiseId": "gid://shopify/ProductVariant/123"
      }
    ],
    "attributes": {
      "key": "cart_attribute_key",
      "value": "This is a cart attribute value"
    }
  }
}

Query a cart

Query a cart by id and return some of the cart's objects. See documentation here for comprehensive list: https://shopify.dev/api/storefront/latest/queries/cart

query cartQuery($cartId: ID!) {
  cart(id: $cartId) {
    id
    createdAt
    updatedAt
    checkoutUrl
    lines(first: 10) {
      edges {
        node {
          id
          quantity
          merchandise {
            ... on ProductVariant {
              id
            }
          }
          attributes {
            key
            value
          }
        }
      }
    }
    attributes {
      key
      value
    }
    cost {
      totalAmount {
        amount
        currencyCode
      }
      subtotalAmount {
        amount
        currencyCode
      }
      totalTaxAmount {
        amount
        currencyCode
      }
      totalDutyAmount {
        amount
        currencyCode
      }
    }
    buyerIdentity {
      email
      phone
      customer {
        id
      }
      countryCode
    }
  }
}

variables
{
  "cartId": "gid://shopify/Cart/50b74bf9dc2bc7a410053b5ffb31ba51"
}

Update line items

This mutation is used to add a product variant of the same type to the cart. In the below example, the quantity of the variant (in variables.json) is increased and the id and quantity are returned to confirm they are correct.

mutation updateCartLines($cartId: ID!, $lines: [CartLineUpdateInput!]!) {
  cartLinesUpdate(cartId: $cartId, lines: $lines) {
    cart {
      id
      lines(first: 10) {
        edges {
          node {
            id
            quantity
            merchandise {
              ... on ProductVariant {
                id
              }
            }
          }
        }
      }
      cost {
        totalAmount {
          amount
          currencyCode
        }
        subtotalAmount {
          amount
          currencyCode
        }
        totalTaxAmount {
          amount
          currencyCode
        }
        totalDutyAmount {
          amount
          currencyCode
        }
      }
    }
  }
}

variables
{
  "cartId": "gid://shopify/Cart/50b74bf9dc2bc7a410053b5ffb31ba51",
  "lines": {
    "id": "gid://shopify/CartLine/7b9ed49f-830e-4142-9c81-e7f8249863ad?cart=50b74bf9dc2bc7a410053b5ffb31ba51",
    "quantity": 3
  }
}

Update buyer identity

cartBuyerIdentityUpdate is used to associate customer info with a cart and is used to determine international pricing. The below example is updating the buyerIdentity and returning the info (email, phone, delivery address preferences) to ensure that it updated correctly

mutation updateCartBuyerIdentity($buyerIdentity: CartBuyerIdentityInput!, $cartId: ID!) {
  cartBuyerIdentityUpdate(buyerIdentity: $buyerIdentity, cartId: $cartId) {
    cart {
      id
      buyerIdentity {
        email
        phone
        deliveryAddressPreferences {
          ... on MailingAddress {
            address1
            city
            country
            firstName
            lastName
          }
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}

variables
{
  "buyerIdentity": {
    "countryCode": "CA",
    "deliveryAddressPreferences": [
      {
        "deliveryAddress": {
          "address1": "123 Fake St.",
          "city": "Toronto",
          "company": "Shopify",
          "country": "Canada",
          "firstName": "Alice",
          "lastName": "Bob",
          "province": "ON"
        }
      }
    ],
    "email": "[email protected]"
  },
  "cartId": "gid://shopify/Cart/684d5f8c6e463f6057e77c15e34082f0"
}

Retrieve checkout url

Query gets cart by id and returns the cart's checkoutURL. That url directs you to the web checkout flow. More info here: https://shopify.dev/custom-storefronts/checkout/create#shopify-web-checkout

query checkoutURL($cartId: ID!) {
  cart(id: $cartId) {
    checkoutUrl
  }
}

variables
{
  "cartId": "gid://shopify/Cart/50b74bf9dc2bc7a410053b5ffb31ba51"
}

Update cart discount codes

This mutation updates the discount codes applied to a given cart and returns the cart id and discountCodes' 'code' and 'applicable' fields

mutation updateCartDiscountCodes($cartId: ID!, $discountCodes: [String!] ) {
  cartDiscountCodesUpdate(cartId: $cartId, discountCodes: $discountCodes) {
    cart {
      id
      discountCodes{
        code
        applicable
      }
      cost {
        totalAmount {
          amount
          currencyCode
        }
        subtotalAmount {
          amount
          currencyCode
        }
        totalTaxAmount {
          amount
          currencyCode
        }
        totalDutyAmount {
          amount
          currencyCode
        }
      }
    }
    
    userErrors {
      field
      message
    }
  }
}

variables
{
  "cartId": "gid://shopify/Cart/50b74bf9dc2bc7a410053b5ffb31ba51",
  "discountCodes": [
    "10_OFF"
  ]
}

Update cart attributes

Updates the attributes of a given cart. Cart attributes are used to store info that isn't included in the existing cart fields. The variables for this mutation provide an example of such a use case i.e. "attributes": { "key": "gift_wrap", "value": "true" } The key/value can be passed as an object or objects in an array, but in either case the update overwrites the existing attributes.

mutation updateCartAttributes($attributes: [AttributeInput!]!, $cartId: ID!) {
  cartAttributesUpdate(attributes: $attributes, cartId: $cartId) {
    cart {
      id
      attributes{
        key
        value
      }
    }
    userErrors {
      field
      message
    }
  }
}

variables
{
  "attributes": {
    "key": "gift_wrap",
    "value": "true"
  },
  "cartId": "gid://shopify/Cart/50b74bf9dc2bc7a410053b5ffb31ba51"
}

Update cart note

Updates cart note, returns cart id and note. Notes are similiar to cart attributes in that they contain additional info about an order. However, notes can be a string whereas attributes require key/value pairs.

mutation updateCartNote($cartId: ID!) {
  cartNoteUpdate(cartId: $cartId) {
    cart {
      id
      note
      
    }
    userErrors {
      field
      message
    }
  }
}

variables
{
  "cartId": "gid://shopify/Cart/50b74bf9dc2bc7a410053b5ffb31ba51",
  "note": "This is a test note"
}

Remove cart lines

Remove lines from existing cart. Use the cost, subtotal, etc or userError message to confirm that the correct line has been removed. The userError message will let you know if the line in the request does not exist.

mutation removeCartLines($cartId: ID!, $lineIds: [ID!]!) {
  cartLinesRemove(cartId: $cartId, lineIds: $lineIds) {
    cart {
      id
      lines(first: 10){
        edges
        {
          node{
            quantity
            merchandise{
              ... on ProductVariant {
                id
              }
            }
          }
        }
      }
      cost {
        totalAmount {
          amount
          currencyCode
        }
        subtotalAmount {
          amount
          currencyCode
        }
        totalTaxAmount {
          amount
          currencyCode
        }
        totalDutyAmount {
          amount
          currencyCode
        }
      }
    }
    
    userErrors {
      field
      message
    }
  }
}

variables
{
  "cartId": "gid://shopify/Cart/50b74bf9dc2bc7a410053b5ffb31ba51",
  "lineIds": [
    "gid://shopify/CartLine/7b9ed49f-830e-4142-9c81-e7f8249863ad?cart=50b74bf9dc2bc7a410053b5ffb31ba51"
  ]
}

Add cart lines

This mutation adds lines to existing cart, returns the quantity and product id. This mutation also accepts sellingPlanId

mutation addCartLines($cartId: ID!, $lines: [CartLineInput!]!) {
  cartLinesAdd(cartId: $cartId, lines: $lines) {
    cart {
      id
      lines(first: 10){
        edges
        {
          node{
            quantity
            merchandise{
              ... on ProductVariant {
                id
              }
            }
          }
        }
      }
      cost {
        totalAmount {
          amount
          currencyCode
        }
        subtotalAmount {
          amount
          currencyCode
        }
        totalTaxAmount {
          amount
          currencyCode
        }
        totalDutyAmount {
          amount
          currencyCode
        }
      }
    }
    
    
    userErrors {
      field
      message
    }
  }
}

variables
{
  "cartId": "gid://shopify/Cart/e623277ec9e65c98f583268f06900ce7",
  "lines": {
    "merchandiseId": "gid://shopify/ProductVariant/40993523892280",
    "quantity": 3
  }
}


Shop content

Get shop policies

The ShopPolicy object represents a policy that a merchant has configured for their store, such as their refund or privacy policy.

This query displays the different shop policies that can be returned using the Storefront API.

query getShopPolicies {
  shop {
    privacyPolicy {
      id
      body # Policy text, maximum size of 64kb.
      title
    }
    refundPolicy {
      id
      body
      title
    }
    shippingPolicy {
      id
      body
      title
    }
    termsOfService {
      id
      body
      title
    }
    subscriptionPolicy {
      id
      body
      title
    }
  }
}

Get blog by handle

The blog object is an blog published to the online store channel.

Each store can have multiple blogs, and each blog can have many articles (blog posts).

This query fetches a specific blog by it's handle and returns the blog along with it's associated articles.

Blogs are meant to be used as a type of magazine or newsletter for the shop, with content that changes over time.

If your shop needs a static page (such as an "About Us" page), we recommend that you use a Page instead.

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

variables
{
  "handle": "my-blog"
}

Get page by handle

The page object represents a custom page on the online store.

Shopify merchants can create pages to hold static HTML content such as an 'About Us' page.

This simple query fetches a page by it's handle and returns the title and description of the page, complete with HTML formatting.

query getPageByHandle($handle: String!) {
  page(handle: $handle) {
    id
    title
    body # The description of the page, complete with HTML formatting.
  }
}

variables
{
  "handle": "my-page"
}


More Repositories

1

draggable

The JavaScript Drag & Drop library your grandparents warned you about.
JavaScript
17,927
star
2

dashing

The exceptionally handsome dashboard framework in Ruby and Coffeescript.
JavaScript
11,025
star
3

liquid

Liquid markup language. Safe, customer facing template language for flexible web apps.
Ruby
10,419
star
4

toxiproxy

⏰ 🔥 A TCP proxy to simulate network and system conditions for chaos and resiliency testing
Go
9,412
star
5

react-native-skia

High-performance React Native Graphics using Skia
TypeScript
6,746
star
6

flash-list

A better list for React Native
TypeScript
5,489
star
7

polaris

Shopify’s design system to help us work together to build a great experience for all of our merchants.
TypeScript
5,352
star
8

hydrogen-v1

React-based framework for building dynamic, Shopify-powered custom storefronts.
TypeScript
3,747
star
9

go-lua

A Lua VM in Go
Go
2,773
star
10

bootsnap

Boot large Ruby/Rails apps faster
Ruby
2,614
star
11

graphql-design-tutorial

2,335
star
12

restyle

A type-enforced system for building UI components in React Native with TypeScript.
TypeScript
2,331
star
13

dawn

Shopify's first source available reference theme, with Online Store 2.0 features and performance built-in.
Liquid
2,279
star
14

identity_cache

IdentityCache is a blob level caching solution to plug into Active Record. Don't #find, #fetch!
Ruby
1,874
star
15

quilt

A loosely related set of packages for JavaScript/TypeScript projects at Shopify
TypeScript
1,703
star
16

shopify_app

A Rails Engine for building Shopify Apps
Ruby
1,649
star
17

kubeaudit

kubeaudit helps you audit your Kubernetes clusters against common security controls
Go
1,624
star
18

shipit-engine

Deployment coordination
Ruby
1,406
star
19

graphql-batch

A query batching executor for the graphql gem
Ruby
1,388
star
20

packwerk

Good things come in small packages.
Ruby
1,346
star
21

krane

A command-line tool that helps you ship changes to a Kubernetes namespace and understand the result
Ruby
1,309
star
22

semian

🐒 Resiliency toolkit for Ruby for failing fast
Ruby
1,286
star
23

slate

Slate is a toolkit for developing Shopify themes. It's designed to assist your workflow and speed up the process of developing, testing, and deploying themes.
JavaScript
1,283
star
24

ejson

EJSON is a small library to manage encrypted secrets using asymmetric encryption.
Go
1,246
star
25

superdb

The Super Debugger, a realtime wireless debugger for iOS
Objective-C
1,158
star
26

shopify_python_api

ShopifyAPI library allows Python developers to programmatically access the admin section of stores
Python
1,072
star
27

storefront-api-examples

Example custom storefront applications built on Shopify's Storefront API
JavaScript
1,069
star
28

themekit

Shopify theme development command line tool.
Go
1,068
star
29

Timber

The ultimate Shopify theme framework, built by Shopify.
Liquid
992
star
30

shopify-cli

Shopify CLI helps you build against the Shopify platform faster.
Ruby
987
star
31

shopify-api-ruby

ShopifyAPI is a lightweight gem for accessing the Shopify admin REST and GraphQL web services.
Ruby
982
star
32

hydrogen

Hydrogen is Shopify’s stack for headless commerce. It provides a set of tools, utilities, and best-in-class examples for building dynamic and performant commerce applications. Hydrogen is designed to dovetail with Remix, Shopify’s full stack web framework, but it also provides a React library portable to other supporting frameworks. Demo store 👇🏼
TypeScript
966
star
33

js-buy-sdk

The JS Buy SDK is a lightweight library that allows you to build ecommerce into any website. It is based on Shopify's API and provides the ability to retrieve products and collections from your shop, add products to a cart, and checkout.
JavaScript
932
star
34

job-iteration

Makes your background jobs interruptible and resumable by design.
Ruby
907
star
35

cli-ui

Terminal user interface library
Ruby
869
star
36

react-native-performance

Performance monitoring for React Native apps
TypeScript
860
star
37

ruby-lsp

An opinionated language server for Ruby
Ruby
851
star
38

active_shipping

ActiveShipping is a simple shipping abstraction library extracted from Shopify
Ruby
809
star
39

shopify-api-js

Shopify Admin API Library for Node. Accelerate development with support for authentication, graphql proxy, webhooks
TypeScript
765
star
40

tapioca

The swiss army knife of RBI generation
Ruby
733
star
41

maintenance_tasks

A Rails engine for queueing and managing data migrations.
Ruby
705
star
42

shopify-app-template-node

JavaScript
701
star
43

remote-ui

TypeScript
701
star
44

erb_lint

Lint your ERB or HTML files
Ruby
651
star
45

shopify_theme

A console tool for interacting with Shopify Theme Assets.
Ruby
640
star
46

pitchfork

Ruby
630
star
47

ghostferry

The swiss army knife of live data migrations
Go
596
star
48

yjit

Optimizing JIT compiler built inside CRuby
593
star
49

statsd-instrument

A StatsD client for Ruby apps. Provides metaprogramming methods to inject StatsD instrumentation into your code.
Ruby
546
star
50

autotuner

Get suggestions to tune Ruby's garbage collector
Ruby
511
star
51

shopify.github.com

A collection of the open source projects by Shopify
CSS
505
star
52

ruby-style-guide

Shopify’s Ruby Style Guide
Ruby
475
star
53

theme-scripts

Theme Scripts is a collection of utility libraries which help theme developers with problems unique to Shopify Themes.
JavaScript
470
star
54

livedata-ktx

Kotlin extension for LiveData, chaining like RxJava
Kotlin
468
star
55

starter-theme

The Shopify Themes Team opinionated starting point for new a Slate project
Liquid
459
star
56

shopify-demo-app-node-react

JavaScript
444
star
57

web-configs

Common configurations for building web apps at Shopify
JavaScript
433
star
58

mobile-buy-sdk-ios

Shopify’s Mobile Buy SDK makes it simple to sell physical products inside your mobile app. With a few lines of code, you can connect your app with the Shopify platform and let your users buy your products using Apple Pay or their credit card.
Swift
433
star
59

shopify_django_app

Get a Shopify app up and running with Django and Python Shopify API
Python
425
star
60

deprecation_toolkit

⚒Eliminate deprecations from your codebase ⚒
Ruby
390
star
61

ruby-lsp-rails

A Ruby LSP extension for Rails
Ruby
388
star
62

bootboot

Dualboot your Ruby app made easy
Ruby
374
star
63

FunctionalTableData

Declarative UITableViewDataSource implementation
Swift
365
star
64

shadowenv

reversible directory-local environment variable manipulations
Rust
349
star
65

shopify-node-app

An example app that uses Polaris components and shopify-express
JavaScript
327
star
66

polaris-viz

A collection of React and React native components that compose Shopify's data visualization system
TypeScript
317
star
67

better-html

Better HTML for Rails
Ruby
311
star
68

theme-check

The Ultimate Shopify Theme Linter
Ruby
306
star
69

product-reviews-sample-app

A sample Shopify application that creates and stores product reviews for a store, written in Node.js
JavaScript
300
star
70

tracky

The easiest way to do motion tracking!
Swift
295
star
71

shopify-api-php

PHP
279
star
72

measured

Encapsulate measurements and their units in Ruby.
Ruby
275
star
73

cli

Build apps, themes, and hydrogen storefronts for Shopify
TypeScript
273
star
74

money

Manage money in Shopify with a class that won't lose pennies during division
Ruby
265
star
75

javascript

The home for all things JavaScript at Shopify.
253
star
76

ruvy

Rust
252
star
77

limiter

Simple Ruby rate limiting mechanism.
Ruby
244
star
78

vscode-ruby-lsp

VS Code plugin for connecting with the Ruby LSP
TypeScript
232
star
79

ruby_memcheck

Use Valgrind memcheck on your native gem without going crazy
Ruby
230
star
80

polaris-tokens

Design tokens for Polaris, Shopify’s design system
TypeScript
230
star
81

buy-button-js

BuyButton.js is a highly customizable UI library for adding ecommerce functionality to any website.
JavaScript
230
star
82

android-testify

Add screenshots to your Android tests
Kotlin
225
star
83

spoom

Useful tools for Sorbet enthusiasts
Ruby
220
star
84

turbograft

Hard fork of turbolinks, adding partial page replacement strategies, and utilities.
JavaScript
213
star
85

mobile-buy-sdk-android

Shopify’s Mobile Buy SDK makes it simple to sell physical products inside your mobile app. With a few lines of code, you can connect your app with the Shopify platform and let your users buy your products using their credit card.
Java
202
star
86

graphql-js-client

A Relay compliant GraphQL client.
JavaScript
187
star
87

shopify-app-template-php

PHP
186
star
88

skeleton-theme

A barebones ☠️starter theme with the required files needed to compile with Slate and upload to Shopify.
Liquid
185
star
89

sprockets-commoner

Use Babel in Sprockets to compile JavaScript modules for the browser
Ruby
182
star
90

rotoscope

High-performance logger of Ruby method invocations
Ruby
180
star
91

shopify-app-template-remix

TypeScript
178
star
92

git-chain

Tool to rebase multiple Git branches based on the previous one.
Ruby
176
star
93

verdict

Framework to define and implement A/B tests in your application, and collect data for analysis purposes.
Ruby
176
star
94

hydrogen-react

Reusable components and utilities for building Shopify-powered custom storefronts.
TypeScript
174
star
95

ui-extensions

TypeScript
173
star
96

heap-profiler

Ruby heap profiler
C++
159
star
97

autoload_reloader

Experimental implementation of code reloading using Ruby's autoload
Ruby
158
star
98

app_profiler

Collect performance profiles for your Rails application.
Ruby
157
star
99

graphql-metrics

Extract as much much detail as you want from GraphQL queries, served up from your Ruby app and the graphql gem.
Ruby
157
star
100

active_fulfillment

Active Merchant library for integration with order fulfillment services
Ruby
155
star