Skip to main contentSkip to Content
Skip to Content
DevelopersMetaobjects & metafields

Metaobjects & metafields

FiveOh stores everything in your Shopify store, as two kinds of Shopify data:

  1. Metafields are extra fields on Shopify’s own objects. FiveOh adds ratings, review lists, AI summaries and sales figures to your products, variants, shop, customers and orders.
  2. Metaobjects are records of their own. Every review is one: Shopify’s standard product_review, plus FiveOh’s review_meta with the translations.

Your theme reads both with Liquid, like any product data. This page lists all of them. If you are new to building on FiveOh, start with Developers.

Metafields

FiveOh keeps ratings, review lists, AI summaries and sales figures as metafields on products, variants, the shop, customers, orders and collections, and updates them whenever a review or an order changes. Liquid reads them like any other metafield:

{%- assign fiveoh = product.metafields['app--324569563137'] -%} {{ fiveoh.rating.value.rating }} out of 5, from {{ fiveoh.rating_count.value }} reviews

The tables below list them by where they live. Each name links to its details further down: type, an example, how to read it, and for JSON values the full structure.

They are readable in the storefront and through the Storefront API, except where noted. Customer account extensions can read the ones on customers, orders and the shop.

On products

MetafieldTypeHolds
ratingRatingAverage rating of the product’s reviews, including its variants’ reviews
rating_countIntegerNumber of reviews behind rating
rating_count_compactTextrating_count shortened for texts, like 12.9k
rating_distributionJSONNumber and share of reviews per star
rating_bucketsList of textsRating steps the product reaches, for rating filters
newest_reviewsList of product_reviewThe product’s reviews, including its variants’, newest first
newest_reviews_metaList of review_metaTranslations and extras of newest_reviews, at the same positions
featured_reviewsList of product_reviewFeatured reviews
featured_reviews_metaList of review_metaTranslations and extras of featured_reviews, at the same positions
review_summary_shortMulti-line textAI summary of the reviews in one line
review_summaryMulti-line textAI summary of the reviews in a few sentences
review_summary_longMulti-line textAI summary of the reviews in a paragraph
live_signalsJSONUnits sold, sales rank and returning customers per period, last purchase
additional_attributesJSONAverages of the attribute answers, like fit
rating_historyJSONReserved: not written yet
most_helpful_reviewsList of product_reviewReserved: not written yet
best_converting_reviewsList of product_reviewReserved: not written yet
newest_reviews_with_mediaList of product_reviewReserved: not written yet

On variants

MetafieldTypeHolds
ratingRatingAverage rating of the variant’s reviews
rating_countIntegerNumber of reviews behind rating
rating_count_compactTextrating_count shortened for texts, like 12.9k
rating_distributionJSONNumber and share of reviews per star
rating_bucketsList of textsRating steps the variant reaches, for rating filters
newest_reviewsList of product_reviewThe variant’s reviews, newest first
newest_reviews_metaList of review_metaTranslations and extras of newest_reviews, at the same positions
featured_reviewsList of product_reviewFeatured reviews of the variant
featured_reviews_metaList of review_metaTranslations and extras of featured_reviews, at the same positions
review_summary_shortMulti-line textAI summary in one line
review_summaryMulti-line textAI summary in a few sentences
review_summary_longMulti-line textAI summary in a paragraph
live_signalsJSONUnits sold, sales rank and returning customers per period, last purchase
additional_attributesJSONAverages of the attribute answers

On the shop

MetafieldTypeHolds
ratingRatingAverage rating of all reviews
rating_countIntegerNumber of all reviews
rating_count_compactTextrating_count shortened for texts, like 12.9k
rating_distributionJSONNumber and share of all reviews per star
product_reviews_ratingRatingAverage rating of product reviews only
product_reviews_rating_countIntegerNumber of product reviews
product_reviews_rating_distributionJSONProduct reviews per star
store_reviews_ratingRatingAverage rating of store reviews only: reviews about the shop itself, not a product, like Trustpilot service reviews
store_reviews_rating_countIntegerNumber of store reviews
store_reviews_rating_distributionJSONStore reviews per star
newest_reviewsList of product_reviewAll reviews of the shop, newest first
newest_reviews_metaList of review_metaTranslations and extras of newest_reviews, at the same positions
featured_reviewsList of product_reviewFeatured reviews of the whole shop
featured_reviews_metaList of review_metaTranslations and extras of featured_reviews, at the same positions
newest_store_reviewsList of product_reviewStore reviews, newest first
newest_store_reviews_metaList of review_metaTranslations and extras of newest_store_reviews
featured_store_reviewsList of product_reviewFeatured store reviews
featured_store_reviews_metaList of review_metaTranslations and extras of featured_store_reviews
review_summary_shortMulti-line textAI summary of all reviews in one line
review_summaryMulti-line textAI summary of all reviews in a few sentences
review_summary_longMulti-line textAI summary of all reviews in a paragraph
live_signalsJSONUnits sold and returning customers of the whole shop per period, last purchase
additional_attributesJSONAverages of the attribute answers across the shop
review_attribute_definitionsJSONThe attribute questions, labels and options, in every shop language
rating_historyJSONReserved: not written yet

On customers

MetafieldTypeHolds
ratingRatingAverage rating of the reviews the customer wrote
rating_countIntegerNumber of reviews the customer wrote
rating_count_compactTextrating_count shortened for texts
rating_distributionJSONThe customer’s reviews per star
newest_reviewsList of product_reviewThe reviews the customer wrote, newest first
newest_reviews_metaList of review_metaTranslations and extras of newest_reviews, at the same positions
additional_attributesJSONAverages of the customer’s attribute answers
review_handlesJSONEvery product and variant the customer reviewed, with the review’s handle

On orders

MetafieldTypeHolds
ratingRatingAverage rating of the reviews written for the order
rating_countIntegerNumber of reviews written for the order
rating_count_compactTextrating_count shortened for texts
rating_distributionJSONThe order’s reviews per star
newest_reviewsList of product_reviewThe reviews written for the order, newest first
newest_reviews_metaList of review_metaTranslations and extras of newest_reviews, at the same positions
additional_attributesJSONAverages of the attribute answers in the order’s reviews
review_requestReference to a review_requestThe order’s review request. Not readable in the storefront
review_request_urlURLLink to the post-purchase review form for the order. Not readable in the storefront

On collections

MetafieldTypeHolds
live_signalsJSONSales rank of the collection’s 50 bestsellers per period

JSON values

All JSON values follow the same conventions:

  1. Keys are in snake_case, like sold_count.
  2. A fixed set of keys is an object. A list that can grow is wrapped as { "items": [ … ] }.
  3. Values ending in _rate go from 0 to 1, values called percent from 0 to 100.
  4. Answers and aggregates store IDs and option keys, never labels. The labels are in review_attribute_definitions.
  5. A lookup by product is an object keyed by the numeric product ID, the product.id of Liquid as text, like sold_ranks.

Metafield details

rating

The average star rating, from 1 to 5, of the reviews that belong to the product, variant, shop, customer or order.

  • Type: Shopify’s rating type
  • On: products (including their variants’ reviews), variants, the shop (all reviews), customers (the reviews they wrote), orders (the reviews written for the order)
  • Example: 4.8
  • Liquid: {{ product.metafields['app--324569563137'].rating.value.rating }}

rating is not a plain number. In Liquid, .value is a rating object:

LiquidReturns
….rating.value.rating4.8
….rating.value.scale_min1.0
….rating.value.scale_max5.0

Read the number with .value.rating; .value alone prints the whole object. Whole numbers come with one decimal, like 5.0; | replace: '.0', '' removes it. Through the Storefront API, the value is a JSON string with value, scale_min and scale_max.

Shopify’s own reviews.rating and reviews.rating_count metafields are written too, but any review app may overwrite them. Read FiveOh’s.

rating_count

The number of reviews behind rating.

  • Type: integer
  • On: products, variants, the shop, customers, orders
  • Example: 126
  • Liquid: {{ product.metafields['app--324569563137'].rating_count.value }}

rating_count_compact

rating_count shortened for texts and tight spaces.

  • Type: single line text
  • On: products, variants, the shop, customers, orders
  • Examples: 950, 12.9k, 1.2m
  • Liquid: {{ shop.metafields['app--324569563137'].rating_count_compact.value }}

rating_distribution

How many reviews give each star, and their share of all reviews.

  • Type: JSON
  • On: products, variants, the shop, customers, orders
  • Liquid: {{ product.metafields['app--324569563137'].rating_distribution.value['5'].percent }}

The keys are the stars as text, "1" to "5", so quote them in Liquid: ['5']. percent goes from 0 to 100.

{ "1": { "count": 0, "percent": 0 }, "2": { "count": 1, "percent": 0.8 }, "3": { "count": 4, "percent": 3.2 }, "4": { "count": 11, "percent": 8.7 }, "5": { "count": 110, "percent": 87.3 } }

rating_buckets

Every rating step the average reaches, for rating filters in Shopify’s Search & Discovery app. A product rated 4.6 reaches every step from 1+ to 4.5+, so a filter on 4+ finds it. 5 is added only for a rating of exactly 5.

  • Type: list of single line texts
  • On: products, variants
  • Example: ["1+", "1.5+", "2+", "2.5+", "3+", "3.5+", "4+", "4.5+"]

product_reviews_rating

The shop’s rating from product reviews only, without store reviews. It comes with two companions:

  • product_reviews_rating: Shopify’s rating type, like rating, example 4.7
  • product_reviews_rating_count: integer, like rating_count, example 1984
  • product_reviews_rating_distribution: JSON, shaped like rating_distribution
  • On: the shop

store_reviews_rating

The shop’s rating from store reviews only: reviews about the shop itself, not about a product. It comes with two companions:

  • store_reviews_rating: Shopify’s rating type, like rating, example 4.9
  • store_reviews_rating_count: integer, like rating_count, example 357
  • store_reviews_rating_distribution: JSON, shaped like rating_distribution
  • On: the shop

newest_reviews

The newest reviews, newest first. It always comes as a pair: newest_reviews holds the product_review metaobjects, newest_reviews_meta the matching review_meta with the translated text and extras.

  • Type: list of metaobject references
  • On: products (including their variants’ reviews), variants, the shop, customers (the reviews they wrote), orders (the reviews written for the order)
  • Holds: up to 250 reviews

The review at position 1 of newest_reviews belongs to the meta at position 1 of newest_reviews_meta, and so on. To read them together, turn the meta list into an array with | compact, then use the loop’s position:

{%- assign fiveoh = product.metafields['app--324569563137'] -%} {%- assign metas = fiveoh.newest_reviews_meta.value | compact -%} {%- for review in fiveoh.newest_reviews.value limit: 10 -%} {%- assign meta = metas[forloop.index0] -%} <h3>{{ meta.title.value }}</h3> <p>{{ meta.body.value }}</p> <p>{{ review.rating.value.rating }} by {{ review.author_display_name.value }}</p> {%- endfor -%}

A Liquid loop over the list stops after 50 reviews; .size still counts all of them. Load the rest with <fo-reviews>. The fields of each review are listed under Metaobjects.

The reviews you featured in the app, with featured_reviews_meta as its pair, like newest_reviews.

  • Type: list of metaobject references
  • On: products, variants, the shop
  • Order: highest featured_priority first, then newest

newest_store_reviews

The newest store reviews, about the shop rather than a product, with newest_store_reviews_meta as its pair.

  • Type: list of metaobject references
  • On: the shop

The featured store reviews, with featured_store_reviews_meta as its pair.

  • Type: list of metaobject references
  • On: the shop

review_summary

An AI summary of what the reviews say, in three lengths. They are empty until there are enough reviews (5 by default).

  • review_summary_short: one line, for product cards
  • review_summary: a few sentences
  • review_summary_long: a full paragraph
  • Type: multi-line text
  • On: products, variants, the shop
  • Liquid: {{ product.metafields['app--324569563137'].review_summary.value | newline_to_br }}

live_signals

Sales figures from the shop’s orders, recalculated regularly: units sold, sales rank and returning customers for four periods, and the time of the last purchase.

  • Type: JSON
  • On: products, variants, the shop, collections
  • Liquid: {{ product.metafields['app--324569563137'].live_signals.value.periods.last_7_days.sold_count }}

The periods are last_24_hours, last_7_days, last_30_days and all_time. Each one holds:

FieldHolds
sold_countUnits sold in the period
sold_count_compactsold_count shortened for texts, like 12.9k
sold_rankPlace among all products by units sold, 1 is the bestseller. Only on products and variants
returning_customer_rateShare of buyers who had ordered from the shop before, from 0 to 1
returning_customer_countNumber of those returning buyers
{ "last_purchased_at": "2026-10-13T08:12:00Z", "periods": { "last_24_hours": { "sold_count": 4, "sold_count_compact": "4", "sold_rank": 12, "returning_customer_rate": 0.25, "returning_customer_count": 1 }, "last_7_days": { "sold_count": 128, "sold_count_compact": "128", "sold_rank": 3, "returning_customer_rate": 0.41, "returning_customer_count": 37 }, "last_30_days": { "sold_count": 512, "sold_count_compact": "512", "sold_rank": 2, "returning_customer_rate": 0.39, "returning_customer_count": 148 }, "all_time": { "sold_count": 12873, "sold_count_compact": "12.9k", "sold_rank": 1, "returning_customer_rate": 0.34, "returning_customer_count": 2950 } } }

On collections, each period holds only sold_ranks: the collection’s 50 bestsellers of the period, by numeric product ID, with their place within the collection. 1 is the collection’s bestseller. A product that sold nothing in the period, or is not among the 50, is missing.

{ "periods": { "last_24_hours": { "sold_ranks": { "15508132626781": 1 } }, "last_7_days": { "sold_ranks": { "15508132626781": 2, "15508132659549": 1 } }, "last_30_days": { "sold_ranks": { "15508132626781": 1, "15508132659549": 3 } }, "all_time": { "sold_ranks": { "15508132626781": 4, "15508132659549": 2 } } } }

In Liquid, collection is the collection being browsed: set on collection pages and on product pages opened from a collection (/collections/shirts/products/...). Anywhere else, pick a collection by its handle, like collections['shirts'].

{%- assign product_key = product.id | append: '' -%} {%- assign place = collection.metafields['app--324569563137'].live_signals.value.periods.last_7_days.sold_ranks[product_key] -%} {%- if place -%} <p>#{{ place }} in {{ collection.title }} this week</p> {%- endif -%}

additional_attributes

The aggregated answers to the attribute questions, like the average fit.

  • Type: JSON
  • On: products, variants, the shop, customers, orders

Every entry in items names its attribute_id and type. What else it holds depends on the type:

TypeFields
star_rating, slider_ratingvalue (the average), count, distribution (like rating_distribution)
choice, yes_nocount, options with count and percent per option key
multiple_choiceLike choice. The percentages refer to the reviewers who answered, so together they can exceed 100
textcount
{ "items": [ { "attribute_id": "fit", "type": "slider_rating", "value": 3.4, "count": 12, "distribution": { "1": { "count": 0, "percent": 0 }, "2": { "count": 1, "percent": 8.3 }, "3": { "count": 6, "percent": 50 }, "4": { "count": 4, "percent": 33.3 }, "5": { "count": 1, "percent": 8.3 } } }, { "attribute_id": "color_accuracy", "type": "choice", "count": 9, "options": { "yes": { "count": 7, "percent": 77.8 }, "no": { "count": 2, "percent": 22.2 } } } ] }

review_attribute_definitions

The attribute questions: their type, question, label and options, each in every shop language.

  • Type: JSON
  • On: the shop
FieldHolds
primary_localeThe shop’s main language
attribute_idThe ID used in all answers and aggregates
typestar_rating, slider_rating, choice, multiple_choice, yes_no or text
label, questionShort name and full question, per language
scale_min, scale_maxRange of star_rating and slider_rating
scale_labelsOptional texts for the left, center and right of a scale, per language
optionsAnswer options of choice and multiple_choice: a key and a label per language
filterableWhether shoppers can filter reviews by it
sort_orderDisplay order
{ "primary_locale": "de", "items": [ { "attribute_id": "fit", "type": "slider_rating", "label": { "de": "Passform", "en": "Fit" }, "question": { "de": "Wie ist die Passform?", "en": "How does it fit?" }, "scale_min": 1, "scale_max": 5, "scale_labels": { "left": { "de": "Fällt klein aus", "en": "Runs small" }, "center": { "de": "Passt genau", "en": "True to size" }, "right": { "de": "Fällt groß aus", "en": "Runs large" } }, "filterable": true, "sort_order": 1 }, { "attribute_id": "color_accuracy", "type": "choice", "label": { "de": "Farbtreue", "en": "Colour accuracy" }, "question": { "de": "Entspricht die Farbe den Fotos?", "en": "Does the colour match the photos?" }, "options": [ { "key": "yes", "label": { "de": "Ja", "en": "Yes" } }, { "key": "no", "label": { "de": "Nein", "en": "No" } } ], "filterable": true, "sort_order": 2 } ] }

Pick the shopper’s language and fall back to the main language:

{{ definition.label[request.locale.iso_code] | default: definition.label[definitions.primary_locale] }}

review_handles

Every product and variant the customer reviewed, with the handle of their review. A review of a variant is listed under the variant’s ID, a review of the product itself under the product’s ID.

  • Type: JSON
  • On: customers
{ "gid://shopify/Product/8123": "rom_form_abc123", "gid://shopify/ProductVariant/45437314170903": "rom_form_def456" }

review_request

The order’s review_request metaobject, see Metaobjects.

  • Type: metaobject reference
  • On: orders
  • Access: customer accounts only; not readable in the storefront

review_request_url

The link to the post-purchase review form for the order, as sent in the review request email.

  • Type: URL
  • On: orders
  • Access: customer accounts only; not readable in the storefront

rating_history

Reserved, not written yet. A monthly history of the rating, each month on its own, not cumulative.

  • Type: JSON
  • On: products, the shop
{ "items": [ { "month": "2026-09", "rating_count": 12, "rating_sum": 55.5, "rating": 4.6 }, { "month": "2026-10", "rating_count": 15, "rating_sum": 64.5, "rating": 4.3 } ] }

Metaobjects

Every review is stored as two metaobjects with the same handle: Shopify’s standard product_review, and FiveOh’s review_meta with everything the standard type has no field for. Read a field with .value, like review.title.value.

product_review

Shopify’s standard metaobject type for product reviews. FiveOh writes these fields:

FieldTypeHolds
ratingRatingThe star rating, from 1 to 5
titleTextTitle, in the language it was written in
bodyTextReview text, in the language it was written in
merchant_replyTextYour reply, in the language you wrote it in
author_display_nameTextPublic author name. Empty for anonymous reviews
authorCustomer referenceThe customer who wrote the review
orderOrder referenceThe order the review belongs to
productProduct referenceThe reviewed product
product_variantVariant referenceThe reviewed variant. Empty for reviews of the whole product
submitted_atDate and timeWhen the review was written
published_atDate and timeWhen it was published
edited_atDate and timeWhen it was last edited
merchant_replied_atDate and timeWhen you replied
sourceTextWhere it comes from, as {platform}_{id}, like reviewsio_123
languageTextLanguage of the original text, like de
app_verification_statusTextverified_buyer, verified_reviewer or unverified
media_urlsJSONList of image and video URLs

For the text in the shopper’s language, read title, body and merchant_reply from the review_meta instead.

review_meta

One per review, with the same handle as its product_review. It is translatable: Liquid returns the text in the shopper’s language. Customers can read their own in customer accounts.

Its type is app--324569563137--review_meta in theme code and $app:review_meta inside FiveOh’s blocks. To look up a review by its handle, for example one from review_handles, read both metaobjects:

{%- assign review = metaobjects.product_review[handle] -%} {%- assign meta = metaobjects['app--324569563137--review_meta'][handle] -%} {{ meta.title.value }}
FieldTypeHolds
titleTextTitle, translated
bodyTextReview text, translated
merchant_replyTextYour reply, translated
additional_attributesJSONThe reviewer’s answers to the attribute questions
featured_priorityInteger0 when not featured. Higher values show first
upvote_countIntegerReserved: not written yet
downvote_countIntegerReserved: not written yet

additional_attributes holds one entry per answered question. A multiple_choice answer is a list of option keys:

{ "items": [ { "attribute_id": "fit", "value": 4 }, { "attribute_id": "color_accuracy", "value": "yes" }, { "attribute_id": "colors", "value": [ "black", "navy" ] } ] }

review_request

One per order, created when FiveOh plans a review request email. Its type is $app:review_request. Customers can read their own order’s in customer accounts.

FieldTypeHolds
orderOrder referenceThe order
itemsJSONThe products to review
email_statusTextpending, sent or skipped
email_countIntegerNumber of review request emails sent
last_email_sent_atDate and timeWhen the last email was sent
reward_discount_codeTextThe discount code sent as a thank-you for the review
reward_email_sent_atDate and timeWhen the reward email was sent

items holds one entry per product of the order:

{ "items": [ { "product": "gid://shopify/Product/8123", "product_variant": "gid://shopify/ProductVariant/45437314170903", "product_handle": "merino-sneaker", "product_title": "Merino Sneaker", "variant_title": "42 / Grey", "url": "https://example.com/products/merino-sneaker", "product_image_url": "https://cdn.shopify.com/s/files/merino-sneaker.jpg", "variant_image_url": null, "excluded": false, "review_handle": "rom_form_abc123", "submitted_at": "2026-10-13T08:12:00Z" } ] }
FieldHolds
product, product_variantThe product and variant, as Shopify IDs
product_handle, product_title, variant_titleFor showing the item
urlThe product’s page in the online store
product_image_url, variant_image_urlImages; variant_image_url is null when the variant has none
excludedtrue when a review request rule excludes the item
review_handle, submitted_atSet once the item was reviewed through the post-purchase form

post_purchase_review_request

The page the review request email links to. Its type is $app:post_purchase_review_request, and its only field is title.

Last updated on