GraphQL

Efficiently Extract Object References in Shopify Storefront GraphQL API

William Mimura
4 min read
Extract object references in shopify storefront graphql api
This article was written over 18 months ago and may contain information that is out of date. Some content may still be relevant, but please refer to official documentation for the latest information.

Efficiently Extract Object References in Shopify Storefront GraphQL API

Introduction

So, this blog post is born out of necessity and a bit of frustration. If you're diving into the world of Shopify's Storefront API, you've probably realized that while it's powerful, extracting data in the object reference from Metadata fields or Metaobjects (in the GraphQL query) can be a bit like searching for a needle in a haystack. This complexity often arises not from the API's lack of capabilities but from the sparse and sometimes unclear documentation on this specific aspect.

That's precisely why I decided to create this post. As a developer, I found myself in a situation where the documentation and community resources were either scarce or not detailed enough for the specific challenges I faced. This guide is the result of my journey - from confusion to clarity.

The Situation

To understand the crux of my challenge, it's essential to recognize that creating metafields and metaobjects is a common practice for those seeking a more customized and controlled experience with Shopify CMS. In my specific case, I wanted to enrich the information available for each product's vendor beyond what Shopify typically allows, which is just a single text box. I aimed to have each vendor display their name and two versions of their logo: a themed logo that aligns with my website's color scheme and an original logo for use on specific pages.

configuration for the custom vendor metaobject

details of the original logo field in the vendor object - the vendor is a file image field

The challenge emerged when I fetched a list of all vendors to display on a page. My GraphQL query for the Storefront API looked like this:

query vendorsMetaObjects($country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
    vendorsCollection: metaobjects(type: "vendor", first: ${MAX_PAGE_BY}) {
        nodes {
            name: field(key: "name") {
                value
            }
            originalLogo: field(key: "original_logo") {
                value
            }
            themedLogo: field(key: "themed_logo") {
                value
            }
        }
    }
}

This was when I hit a roadblock. How do I fetch a field with a more complex type than a simple text or number, like an image? To retrieve the correct data, what specific details must I include in the originalLogo and themedLogo fields?

In my quest for a solution, I turned to every resource I could think of. I combed through the Storefront API documentation, searched endlessly on Stack Overflow, and browsed various tech forums. Despite all these efforts, I couldn’t find the clear, detailed answers I needed. It felt like I was looking for something that should be there but wasn’t.

Solution

Before diving into the solution, it's important to note that this is the method I discovered through trial and error. There might be other approaches, but I want to share the process that worked for me without clear documentation.

My first step was to understand the nature of the data returned by the Storefront API. I inspected the value of a metaobject, which looked something like this:

{
  "name": { "value": "A Vendor Test 1" },
  "originalLogo": { "value": "gid://shopify/MediaImage/some_ID" },
  "themedLogo": { "value": "gid://shopify/MediaImage/some_other_ID" }
}

The key here was the gid, or global unique identifier. What stood out was that it always includes the object type, in this case, MediaImage. This was crucial because it indicated which union to use and what properties to query from this object in the Storefront API documentation.

So, I modified my query to include a reference to this object type, focusing on the originalLogo field as an example:

query vendorsMetaObjects($country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
    vendorsCollection: metaobjects(type: "vendor", first: ${MAX_PAGE_BY}) {
        nodes {
            # ...
            originalLogo: field(key: "original_logo") {
                value
                reference {
                    ... on MediaImage {
                        # Explore MediaImage documentation for extractable fields
                    }
                }
            }
            # ...
        }
    }
}

The next step was to consult the Storefront API documentation for MediaImage at Shopify API Documentation. Here, I discovered the image field within MediaImage, an object containing the url field. With this information, I updated my query:

query vendorsMetaObjects($country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
    vendorsCollection: metaobjects(type: "vendor", first: ${MAX_PAGE_BY}) {
        nodes {
            name: field(key: "name") {
                value
            }
            originalLogo: field(key: "original_logo") {
                reference {
                    ... on MediaImage {
                        image {
                            url
                        }
                    }
                }
            }
            themedLogo: field(key: "themed_logo") {
                reference {
                    ... on MediaImage {
                        image {
                            url
                        }
                    }
                }
            }
        }
    }
}

Finally, when executing this query, the output for a single object was as follows:

{
  "name": { "value": "A Vendor Test 1" },
  "originalLogo": {
    "reference": {
      "image": {
        "url": "https://cdn.shopify.com/s/files/rest_of_the_url"
      }
    }
  },
  "themedLogo": {
    "reference": {
      "image": {
        "url": "https://cdn.shopify.com/s/files/rest_of_the_url"
      }
    }
  }
}

Through this process, I successfully extracted the necessary data from the object references in the metafields, specifically handling more complex data types like images.

Conclusion

In wrapping up, it's vital to emphasize that while this guide focused on extracting MediaImage data from Shopify's Storefront API, the methodology I've outlined is broadly applicable. The key is understanding the structure of the gid (global unique identifier) and using it to identify the correct object types within your GraphQL queries.

Whether you're dealing with images or any other data type defined in Shopify's Storefront API, this approach can be your compass. Dive into the API documentation, identify the object types relevant to your needs, and adapt your queries accordingly. It's a versatile strategy that can be tailored to suit many requirements.

Remember, the world of APIs and e-commerce is constantly evolving, and staying adaptable and resourceful is crucial. This journey has been a testament to the power of perseverance and creative problem-solving in the face of technical challenges. May your ventures into Shopify's Storefront API be equally rewarding and insightful.

About the author

William Mimura

William Mimura

Senior Software Engineer

Keep reading

View all posts →

How to Leverage Apollo Client Fetch Policies Like the Pros

Apollo Client provides a rich ecosystem and cache for interfacing with your GraphQL APIs. You write your query and leverage the `useQuery` hook to fetch your data....

Dustin Goodman7 mins
GraphQL

How to create and use custom GraphQL Scalars

Enter the world of custom GraphQL scalars. These data types go beyond the conventional, offering the power and flexibility to tailor your schema to precisely match your application's unique needs. ...

William Mimura5 mins
GraphQLJavaScript

Leveraging GraphQL Scalars to Enhance Your Schema

Explore the transformative power of GraphQL scalars with the graphql-scalars library, designed to extend the default scalar types in GraphQL schemas. ...

William Mimura4 mins
GraphQL

Build Beautiful Storefronts Quickly with Shopify and Next

Introduction Shopify is one of the world’s best e commerce platforms for building online stores of any size. It’s a hosted platform, which means you don’t have to worry about the technical details of managing a server or dealing with software updates. You can focus on building your business instead. Next.js is a React framework for building static and server side rendered applications. It’s a great choice for building e commerce storefronts and enables you to do more customization, and it’s what we’ll be using in this article. Shopify Next.js Starter Kit Recently, we’ve created a starter kit that you can use to build your own Shopify storefront with Next.js. It’s a great way to get started quickly especially since it is powered by the new App Router and React Server Components, and it’s completely free. You can find it on GitHub here: Shopify Next.js Starter Kit We also have a live demo of the starter kit here: Shopify Next.js Starter Kit Demo Getting Started To get started, open your terminal and run the following command: And choose Shopify, NextJS 13.4 and Tailwind CSS Then, choose the project name And everything ready to go, next steps are to go to the directory and install the packages Setup Shopify Account Next, you’ll need to create a Shopify store. There are two ways to get a Shopify account: 1 You can do this by going to Shopify and clicking on the “Start free trial” button and create a Shopify account. 2 Or you can create a Shopify Partner Account for development purposes Once you’ve created your store, you’ll need to create a private app. You can do this by going to the “Apps” section of your Shopify admin and clicking on the “Manage private apps” link. Then click on the “Create a new private app” button. Give your app a name, and then click on the “Save” button. You’ll then be taken to a page where you can see your API credentials. You’ll need to copy these credentials into your .env.local file. You can find the .env.local file at the root of your project. It should look something like this: Modify the design After adding the required secrets, run npm run dev to run the development server locally The project structure is simple and easy. Since we are using the App Router, all of the routes are under /app folder and the shared components are under /components folder. This structure make it easy for you to edit and modify easily on the design Also all of the components have been written in a clean way with Tailwind CSS to make it easy for you to edit it. Deploy Since it’s a Next.js project, its deployment is easier than ever, most of the modern host providers support deploying it with just one click like Vercel Netlify Cloudflare Page AWS Amplify Render Fly.io Just push the project to a remote git repository using GitHub and connect it to the hosting provider of your choice. Conclusion In this article, we’ve shown you how to build a Shopify storefront with Next.js with our new starter kit from Starter.dev. We’ve also shown you how to use the new App Router and React Server Components to build a fast and performant storefront. We hope you’ve enjoyed this article and found it useful. If you have any questions or comments, please feel free to reach out to us on Twitter or GitHub. We’d love to hear from you!...

Mark Shenouda4 mins
NextJSShopify