Product
An easy way to access and use Shopify Product data within the Superfans SDK.
Description
The product variable provides details about the product on a Product Detail (PDP) page. It includes the product ID, title, handle, description, images, options, variants, collections, metafields, and the currently selected variant.
This object is only available on PDP pages. Outside of a PDP context, it is null.
On mobile app initial load, selectedVariant may be null. If it is missing, use the first available variant from product.variants. Check availability on the variant with variant.availableForSale.
Properties of product
| Property | Type | Scope | Description | Example |
|---|---|---|---|---|
product.id | String | PDP | Unique id of the product. | 1234567890 |
product.productType | String | PDP | Shopify product type. Can be an empty string. | empty |
product.handle | String | PDP | User-friendly slug used in the product URL. | sample-product |
product.title | String | PDP | Name of the product. | Sample product |
product.description | String | PDP | HTML description of the product. | <p>Product description</p> |
product.vendor | String | PDP | Name of the vendor or brand. | Brand |
product.images | String[] | PDP | Array of product image URLs. | See sample product object |
product.tags | String[] | PDP | Array of Shopify tags attached to the product. | See sample product object |
product.availableforSale | Boolean | PDP | Whether the product is available for purchase. The live key is availableforSale (lowercase f). | true |
product.selectedVariant | Object | PDP | Currently selected variant. Can be null on initial mobile load. Same shape as a variants entry. | See properties of variants |
product.variants | Object[] | PDP | All product variants. | See properties of variants |
product.options | Object[] | PDP | Product option definitions. Each entry has id, name, and optionValues. | See sample product object |
product.collections | Object[] | PDP | Collections this product belongs to. Each entry has id, title, and handle. | See sample product object |
product.metafields | Object | PDP | Map of metafield handles to values. Missing metafields are null. | See sample product object |
product.klaviyo | Object | PDP | Klaviyo state: enabled, isOutOfStock, and isSubscribed. | See sample product object |
Properties of variants
product.selectedVariant uses this same shape when it is present.
| Property | Type | Scope | Description | Example |
|---|---|---|---|---|
product.variants.id | String | PDP | Unique id of the variant. | 1111111111 |
product.variants.title | String | PDP | Display name of the variant. | Black |
product.variants.price | String | PDP | Price as a string, not a number. | 110.0 |
product.variants.image | String | PDP | Single image URL for the variant. This is not an array. | https://cdn.shopify.com/image.jpg |
product.variants.sku | String | PDP | Stock keeping unit. Can be null. | null |
product.variants.quantityAvailable | Integer | PDP | Inventory quantity available for the variant. | 100 |
product.variants.availableForSale | Boolean | PDP | Whether this variant can be purchased. Use this field. Do not use isAvailable. | true |
product.variants.currencyCode | String | PDP | ISO currency code for the variant price. | USD |
product.variants.selectedOptions | Object[] | PDP | Option name and value pairs selected for this variant. Each entry has name and value. | See sample product object |
product.variants.sellingPlanAllocations | Object[] | PDP | Selling plan allocations for the variant. Empty array when the variant has no selling plans. | See properties of sellingPlanAllocations |
Properties of sellingPlanAllocations
Use sellingPlanId as-is when calling addToCart or buyNow.
| Property | Type | Scope | Description | Example |
|---|---|---|---|---|
product.variants.sellingPlanAllocations.sellingPlanId | String | PDP | Shopify selling plan GID. Always starts with gid://shopify/SellingPlan/. | gid://shopify/SellingPlan/selling_plan_id |
product.variants.sellingPlanAllocations.label | String | PDP | Display name of the selling plan. | Deliver every month |
product.variants.sellingPlanAllocations.intervalCount | Integer | PDP | Billing interval count. Can be null. | 1 |
product.variants.sellingPlanAllocations.intervalUnit | String | PDP | Billing interval unit, such as MONTH. Can be null. | MONTH |
product.variants.sellingPlanAllocations.priceAmount | Number | PDP | Subscription price amount. | 99 |
product.variants.sellingPlanAllocations.compareAtAmount | Number | PDP | Compare-at amount used for savings. Can be 0. | 110 |
product.variants.sellingPlanAllocations.perDeliveryAmount | Number | PDP | Per-delivery price amount. | 99 |
product.variants.sellingPlanAllocations.currencyCode | String | PDP | ISO currency code for the plan prices. | USD |
product.variants.sellingPlanAllocations.percentageDiscount | Integer | PDP | Percentage discount versus compare-at. Can be 0. | 10 |
product.variants.sellingPlanAllocations.checkoutChargeAmount.amount | Number | PDP | Amount charged at checkout. | 99 |
product.variants.sellingPlanAllocations.checkoutChargeAmount.currencyCode | String | PDP | ISO currency code for the checkout charge. | USD |
Sample product object
{"id":"1234567890","productType":"","handle":"sample-product","title":"Sample product","description":"<p>Product description</p>","vendor":"Brand","images":["https://cdn.shopify.com/image.jpg"],"tags":["new"],"availableforSale":true,"metafields":{"custom_key":null},"klaviyo":{"enabled":false,"isOutOfStock":false,"isSubscribed":false},"collections":[{"id":"123456789","title":"Sample collection","handle":"sample-collection"}],"options":[{"id":"gid://shopify/ProductOption/option_id","name":"Color","optionValues":[{"id":"gid://shopify/ProductOptionValue/option_value_id","name":"Black","swatch":{"color":"#000000","image":null}}]}],"selectedVariant":{"id":"1111111111","title":"Black","price":"110.0","image":"https://cdn.shopify.com/image.jpg","sku":null,"quantityAvailable":100,"availableForSale":true,"currencyCode":"USD","selectedOptions":[{"name":"Color","value":"Black"}],"sellingPlanAllocations":[{"sellingPlanId":"gid://shopify/SellingPlan/selling_plan_id","label":"Deliver every month","intervalCount":1,"intervalUnit":"MONTH","priceAmount":99,"compareAtAmount":110,"perDeliveryAmount":99,"currencyCode":"USD","percentageDiscount":10,"checkoutChargeAmount":{"amount":99,"currencyCode":"USD"}}]},"variants":[{"id":"1111111111","title":"Black","price":"110.0","image":"https://cdn.shopify.com/image.jpg","sku":null,"quantityAvailable":100,"availableForSale":true,"currencyCode":"USD","selectedOptions":[{"name":"Color","value":"Black"}],"sellingPlanAllocations":[{"sellingPlanId":"gid://shopify/SellingPlan/selling_plan_id","label":"Deliver every month","intervalCount":1,"intervalUnit":"MONTH","priceAmount":99,"compareAtAmount":110,"perDeliveryAmount":99,"currencyCode":"USD","percentageDiscount":10,"checkoutChargeAmount":{"amount":99,"currencyCode":"USD"}}]}]}Example Usage
const product = Superfans.variables.product;
if (product) {
const variant = product.selectedVariant || product.variants?.[0];
console.log("Product: " + product.title);
if (variant) {
console.log("Variant: " + variant.title);
const sellingPlanId = variant.sellingPlanAllocations?.[0]?.sellingPlanId;
if (sellingPlanId) {
console.log("Selling plan GID: " + sellingPlanId);
}
}
} else {
console.log("Not on a product page.");
}Best Practices
- Check for null:
productis only defined on PDP pages. - Re-read live product data: Inside
Superfans.listeners.onVariantChanged, readSuperfans.variables.productagain instead of using a cached product or variant. - Handle a null selected variant: On initial mobile load, fall back to
product.variants[0]. - Pass selling plan GIDs as-is: Copy
sellingPlanAllocations[].sellingPlanIdintoaddToCartorbuyNow. Do not stripgid://or pass a numeric id. - Read-only data: Do not modify product or variant objects.
Caveats
- Scope limited to PDP:
productisnullon any page that is not a product detail page. - Product vs variant availability keys: The product uses
availableforSale(lowercasef). Each variant usesavailableForSale. - Variant image is a string:
variants[].imageis one URL, not an array of URLs. - Selling plans:
sellingPlanAllocationsis an array on each variant.sellingPlanIdis a Shopify GID (gid://shopify/SellingPlan/...). The array is empty when the variant has no selling plans.
Updated 22 days ago
Did this page help you?