Creating and Accessing Metaobjects in Shopify Hydrogen with GraphQL

ajay shanbhagajay shanbhag
6 min read

Understanding Metaobjects in Shopify

Metaobjects in Shopify are a powerful way to add and manage structured, reusable data for your store, such as product features, size charts, or ambassador profiles. Unlike metafields, which store single key-value pairs, metaobjects allow you to create complex data structures with multiple fields, making them ideal for dynamic content in headless storefronts like those built with Shopify Hydrogen.

What Are Metaobjects?

Metaobjects consist of two core components:

  • Definition: The blueprint of the metaobject, specifying its structure. You create this in Settings > Custom Data > Metaobjects in your Shopify Admin. It includes:

    • Name: A user-friendly identifier, like "Product Highlights."

    • Type: A unique identifier for the data type (e.g., product_highlight).

    • Fields: The data types you want to store, such as text, images, or URLs. Each field has:

      • A required name.

      • An optional description.

      • A type (e.g., single-line text, file, number).

      • Validation rules (e.g., character limits or preset values).

    • Display Name: A field (usually text) used to identify individual entries, automatically assigned to the first text field or autogenerated if none exists.

    • Options: Settings to control where the metaobject can be used (e.g., Storefront API access).

  • Entries: The actual content for the metaobject, managed in Content > Metaobjects. Each entry follows the structure defined by the metaobject. For example, a "Product Highlights" metaobject might have entries for "Water Resistance" or "Lightweight Design," each with a name, description, and image.

Why Use Metaobjects?

Metaobjects are versatile and can be accessed in multiple ways:

  • Shopify Admin: Create, edit, and manage entries directly.

  • Storefront API: Fetch metaobject data in Hydrogen apps using GraphQL.

For example, you could create a metaobject for "Ambassador Profiles" with fields for name, biography, and image. Each entry represents a single ambassador, which you can display on a Hydrogen storefront.

Real-World Example: Product Categories

Shopify’s Standard Product Taxonomy uses metaobjects to manage category metafields. If you assign a product to the category Apparel & Accessories > Clothing > Shirts, you can add metafields like size, neckline, sleeve length, fabric, or color. These metafields are powered by metaobject definitions with default entries, ensuring consistent data across products.

Getting Started

To use metaobjects in your Hydrogen app:

  1. Create a metaobject definition in Shopify Admin.

  2. Add entries under Content > Metaobjects.

  3. Query the data using the Storefront API (covered in the next section).

For more details, check Shopify’s metaobject documentation. https://help.shopify.com/en/manual/custom-data/metaobjects

Example: Displaying a Product Highlight in Shopify Hydrogen

Let’s walk through a simple example of creating a "Product Highlight" metaobject, adding an entry, and displaying it in a Hydrogen app using a GraphQL query.

Step 1: Create the Metaobject in Shopify Admin

  1. Navigate: Go to Settings > Custom Data > Metaobjects in your Shopify Admin.

  2. Create Definition:

    • Name: Product Highlight

    • Type: product_highlight

    • Fields:

      • title (Single-line text, set as Display Name)

      • description (Multi-line text)

      • image (File, for an image upload)

    • Options: Enable Storefronts access for the Storefront API.

      • Step 2: Create a GraphQL Folder Structure

        Organize your GraphQL queries in a dedicated folder to keep your codebase clean.

        1. Create the Folder:

          • In your Hydrogen project, create a graphql folder at the root or under app (e.g., app/graphql).

          • Within graphql, create a subfolder for metaobject-related queries, such as graphql/meta-objects.

        2. Add the Query File:

          • Create a file named ProductHighlightQuery.ts in app/graphql/meta-objects.

          • Export the GET_PRODUCT_HIGHLIGHT query as a constant, formatted for use with Shopify’s Storefront API.

                // app/graphql/meta-objects/ProductHighlightQuery.ts
                export const GET_PRODUCT_HIGHLIGHT = `#graphql
                  query getProductHighlight($type: String!, $handle: String!) {
                    metaobject(handle: { type: $type, handle: $handle }) {
                      id
                      title: field(key: "title") { value }
                      description: field(key: "description") { value }
                      image: field(key: "image") {
                        reference {
                          ... on MediaImage {
                            image {
                              url
                              altText
                            }
                          }
                        }
                      }
                    }
                  }
                ` as const;

Note: The as const assertion ensures the query string is treated as a literal type, which is necessary for TypeScript and codegen to work correctly.

Step 3: Run npm run codegen and Inspect Generated Types

Running the codegen command integrates your GraphQL queries with Shopify’s Storefront API schema, producing type definitions that make your code more robust.

  1. Run the Command:

    • In your terminal, navigate to your Hydrogen project directory and execute:

        npm run codegen
      
    • This command scans your GraphQL queries (like GET_PRODUCT_HIGHLIGHT) and generates TypeScript types in storefrontapi.generated.d.ts.

  2. Inspect the Generated Types:

    • After running codegen, open storefrontapi.generated.d.ts to find the generated types for the GET_PRODUCT_HIGHLIGHT query. You’ll see something like this:
                export type GetProductHighlightQueryVariables = StorefrontAPI.Exact<{
                  type: StorefrontAPI.Scalars['String']['input'];
                  handle: StorefrontAPI.Scalars['String']['input'];
                }>;

                export type GetProductHighlightQuery = {
                  metaobject?: StorefrontAPI.Maybe<
                    Pick<StorefrontAPI.Metaobject, 'id'> & {
                      title?: StorefrontAPI.Maybe<Pick<StorefrontAPI.MetaobjectField, 'value'>>;
                      description?: StorefrontAPI.Maybe<
                        Pick<StorefrontAPI.MetaobjectField, 'value'>
                      >;
                      image?: StorefrontAPI.Maybe<{
                        reference?: StorefrontAPI.Maybe<{
                          image?: StorefrontAPI.Maybe<
                            Pick<StorefrontAPI.Image, 'url' | 'altText'>
                          >;
                        }>;
                      }>;
                    }
                  >;
                };
  1. Understand the Types:

    • GetProductHighlightQueryVariables: Defines the input variables for the query (type and handle), both required strings. The StorefrontAPI.Exact ensures exact matching of variable names and types.

    • GetProductHighlightQuery: Describes the query response structure:

      • metaobject?: The response may or may not return a metaobject (optional due to Maybe).

      • id: The metaobject’s unique identifier.

      • title? and description?: Optional fields containing the value of the respective metaobject fields.

      • image?: An optional field with a nested reference that may contain an image object with url and altText.

    • The Maybe wrapper (from Shopify’s Storefront API types) indicates that fields can be null or undefined, encouraging safe handling in your code.

Step 4: Fetching and Displaying Product Highlights on the Homepage

After organizing the GET_PRODUCT_HIGHLIGHT query in app/graphql/meta-objects/ProductHighlightQuery.ts and generating TypeScript types with npm run codegen, you can integrate the query into your Hydrogen homepage (app/routes/index.tsx). This step shows how to fetch the "Product Highlight" metaobject using deferred loading and display it with a dedicated component, ensuring a performant and modular storefront.

Adding the Query to Deferred Data

In the loadDeferredData function, add the GET_PRODUCT_HIGHLIGHT query to fetch the product highlight metaobject alongside other deferred queries like hero banners and recommended products. This approach keeps the page responsive by loading non-critical data asynchronously.

  1. Update the loadDeferredData Function:

    • Import the GET_PRODUCT_HIGHLIGHT query and its type (GetProductHighlightQuery).

    • Add a query for the product highlight with a specific handle (e.g., water-resistance).

    • Include error handling to gracefully handle API failures.

  2. Create the ProductHighlightSection Component:

    • Add a component to render the metaobject’s title, description, and image, using Suspense and Await for deferred loading.

    • Style it consistently with other homepage sections (e.g., HeroBannerSection).

3. Here’s the updated homepage code with the product highlight integrated:
function ProductHighlightSection({ productHighlight, }: { productHighlight: Promise<GetProductHighlightQuery | null>; }) { return ( <div className="product-highlight"> <Suspense fallback={<div>Loading...</div>}> <Await resolve={productHighlight}> {(response) => { const highlight = response?.metaobject; return ( <div> {highlight ? ( <div> <h2>{highlight.title?.value}</h2> <p>{highlight.description?.value}</p> {highlight.image?.reference?.image && ( <img src={highlight.image.reference.image.url} alt={highlight.image.reference.image.altText || 'Product Highlight'} width="200" /> )} </div> ) : ( <div>No product highlight found.</div> )} </div> ); }} </Await> </Suspense> </div> ); }

  • Step 5: Visualizing the Product Highlight on the Homepage

    With the GET_PRODUCT_HIGHLIGHT query added to loadDeferredData and the ProductHighlightSection component integrated into app/routes/index.tsx, your Hydrogen homepage now showcases a "Product Highlight" section. This step explores the rendered output, helping you understand what users will see and how to enhance it for an engaging storefront experience.

    Happy

0
Subscribe to my newsletter

Read articles from ajay shanbhag directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

ajay shanbhag
ajay shanbhag