Overview
In Shopify, the Product object is the core catalog entity. Shopify enforces an explicit hierarchical relationship between products, options, and product variants across all APIs and themes.
Shopify Product
├── Options (e.g. Size, Color)
└── Variants (ProductVariant)
├── Price & CompareAtPrice
├── InventoryItem & InventoryLevels
└── SelectedOptions
Liquid Theme Context
In Shopify Liquid theme templates (product.liquid or sections/main-product.liquid), the global product object exposes:
product.title: Product title string.product.variants: Array ofvariantobjects.product.selected_or_first_available_variant: Helper returning the active variant based on URL parameters (?variant=123456) or the first variant in stock.product.options_with_values: Array of option names and available values (e.g.Size: [S, M, L]).
{% comment %} Rendering Variant Selector in Liquid {% endcomment %}
<select name="id">
{% for variant in product.variants %}
<option value="{{ variant.id }}" {% if variant == product.selected_or_first_available_variant %}selected{% endif %}>
{{ variant.title }} - {{ variant.price | money }}
</option>
{% endfor %}
</select>
GraphQL API Data Structure
In Shopify’s Admin and Storefront GraphQL APIs, products are fetched using node queries:
query getProductByHandle($handle: String!) {
product(handle: $handle) {
id
title
descriptionHtml
variants(first: 10) {
edges {
node {
id
title
sku
price {
amount
currencyCode
}
availableForSale
}
}
}
}
}
Shopify Platform Constraints
Developer Takeaway
Shopify GID Format: In GraphQL API integrations, Shopify IDs are global identifiers formatted as URIs (e.g. gid://shopify/Product/123456789 and gid://shopify/ProductVariant/987654321). Always handle GIDs cleanly when parsing API responses.