Skip to content
Published Authored byBilly Reiner

Schema · How-to

Shopify shippingDetails schema

shippingDetails is the Offer property that declares shipping costs, destinations, and delivery time for a product1. Its value is an OfferShippingDetails object with shippingRate (MonetaryAmount), shippingDestination (DefinedRegion with addressCountry), and deliveryTime (ShippingDeliveryTime with handlingTime + transitTime). Third-party SEO publications throughout 2026 claim Google AI Overviews now treats this property as effectively required for Product visibility — [UNVERIFIED — third-party only]. Shopify's primary docs do not codify this requirement at our verification window (2026-05-22). We recommend the field anyway, because Google Merchant Center has required it for Shopping eligibility for over a year2.

The 2026 install pattern: emit one or more OfferShippingDetails sub-objects inside Offer on every Shopify PDP, mapping shippingRate to the merchant's actual shipping rates and deliveryTime to the handling + transit windows configured in Shopify Settings > Shipping and delivery3. For free-shipping stores, the block emits shippingRate value 0; for paid shipping, the block emits the real rate per destination region.

What OfferShippingDetails is

Per Schema.org v30.0, OfferShippingDetails 'represents information about shipping destinations.' Multiple OfferShippingDetails objects can attach to one Offer to represent different rates, costs, and delivery times across destinations. Inheritance: Thing > Intangible > StructuredValue > OfferShippingDetails. Key properties: shippingRate (MonetaryAmount or ShippingRateSettings), shippingDestination (DefinedRegion), deliveryTime (ShippingDeliveryTime), doesNotShip (Boolean), shippingOrigin (DefinedRegion).

Mental model: OfferShippingDetails declares the fulfilment story for one destination. A Shopify store shipping to US, Canada, and the UK should ideally emit three OfferShippingDetails sub-objects per product — one per region with the right rate and time for that region. For stores with a flat-rate global shipping policy, one OfferShippingDetails with broad applicability is enough.

The AI Overviews claim — [UNVERIFIED]

Same caveat as hasMerchantReturnPolicy: industry SEO publications throughout Jan–May 2026 repeatedly state Google AI Overviews now demands shippingDetails on Product schema for AI shopping visibility. The claim is not confirmed in Shopify's primary docs or in Google Search Central's AI Overviews policy statements at our verification window. We mark [UNVERIFIED — third-party only] and recommend the field anyway for the reasons in the install rationale below.

OfferShippingDetails fields

The properties Google's documentation strongly recommends and Schema.org defines: shippingRate (a MonetaryAmount with value and currency, OR a ShippingRateSettings reference for stores with rate sets), shippingDestination (a DefinedRegion with addressCountry — ISO 3166-1 alpha-2 — and optionally addressRegion or postalCode ranges), deliveryTime (a ShippingDeliveryTime with handlingTime QuantitativeValue and transitTime QuantitativeValue, both expressed in days).

  • shippingRate — required. MonetaryAmount with value (Number) and currency (Text, ISO 4217). For free shipping, value: '0'.
  • shippingDestination — required. DefinedRegion with addressCountry (one or array). For US only: 'US'. For multi-country: ['US', 'CA', 'GB'].
  • deliveryTime — recommended. ShippingDeliveryTime with handlingTime (QuantitativeValue minValue/maxValue/unitCode 'DAY' — typically 0–1 or 0–2 days) and transitTime (QuantitativeValue minValue/maxValue/unitCode 'DAY' — typically 2–5 or 3–7 days).
  • doesNotShip — optional. Boolean. Use when the merchant doesn't ship to specific regions.
  • shippingOrigin — optional. DefinedRegion. The fulfilment country, useful for international duty calculations.

JSON-LD example — OfferShippingDetails inside Offer

The block below shows shippingDetails inside the Offer sub-object of a Shopify Product block. Hard-coded US-only with $0 shipping and 0–1 day handling + 2–5 day transit. Adjust per the merchant's actual Shopify shipping zone configuration.

JSON-LD shippingDetails inside Offer, inside Product, inside main-product.liquid
 "shippingDetails": { "@type": "OfferShippingDetails", "shippingRate": { "@type": "MonetaryAmount", "value": "0", "currency": "{{ shop.currency }}" }, "shippingDestination": { "@type": "DefinedRegion", "addressCountry": "US" }, "deliveryTime": { "@type": "ShippingDeliveryTime", "handlingTime": { "@type": "QuantitativeValue", "minValue": 0, "maxValue": 1, "unitCode": "DAY" }, "transitTime": { "@type": "QuantitativeValue", "minValue": 2, "maxValue": 5, "unitCode": "DAY" } } } 

Mapping Shopify shipping zones to OfferShippingDetails

Shopify exposes shipping configuration at Settings > Shipping and delivery > Shipping (Shipping zones, with countries per zone and rates per zone). For accurate schema, each zone should map to one OfferShippingDetails sub-object — one for US, one for Canada, one for International. The shippingRate per OfferShippingDetails comes from the cheapest standard rate per zone (the rate most relevant for the structured data). Flat-rate stores can hard-code; multi-zone stores benefit from a Liquid loop over shipping_zone metafields or a custom-built ShippingRateSettings reference.

Validation

Rich Results Test against a PDP with shippingDetails should report Product detected, Offer parsed, OfferShippingDetails parsed, zero errors. Common warnings: 'deliveryTime is recommended' (clears when you add handlingTime + transitTime), 'shippingDestination should include addressCountry' (clears with ISO 3166-1 alpha-2). For Merchant Center, the JSON-LD shippingDetails must agree with the feed's shipping attributes.

A subtle gotcha: Google's validator sometimes objects to unitCode: "DAY" being lowercased. The Schema.org standard is uppercase 'DAY' (per UN/CEFACT code list); always emit uppercase.

Shopify gotchas on shippingDetails

Four gotchas. First: hard-coding shippingRate value '0' on a store with paid shipping — the markup is structurally valid but misrepresents the actual cost, which Merchant Center catches. Use the merchant's real rate. Second: emitting shippingDestination as a single country on a multi-country store, leaving other regions unrepresented. Third: omitting deliveryTime, which makes the OfferShippingDetails structurally minimal but less useful to AI engines deciding which products to recommend. Fourth: using floats for handlingTime / transitTime (handlingTime minValue: 0.5) — Schema.org accepts numbers, but Google's parser sometimes prefers integers.

A fifth gotcha for stores with carrier-calculated shipping (USPS, FedEx, UPS): the actual shipping cost is computed at checkout based on weight/dimensions, not knowable in advance. The honest schema emission is a ShippingRateSettings reference rather than a fixed MonetaryAmount — or a conservative average rate documented as "starting from". Pick one and stick with it; do not emit zero on a store where shipping is genuinely paid.