Skip to content

Technical & compliance blocks

Chapter 7 covers the blocks that sell a product. This chapter covers the blocks that describe one: specification tables, compatibility lists, EU energy and safety disclosures, repair and spare-part information, security-update windows, running costs, documents, questions and ratings.

They exist for two reasons:

  1. Technical shoppers buy on data. A monitor is a resolution, a refresh rate, a panel size and a port list. A table that answers those questions removes the reason to leave for a spec sheet on another site.
  2. A growing part of that data is legally required. GPSR has applied since 13 December 2024. The EU Right to Repair Directive since 31 July 2026. The Cyber Resilience Act applies in full from 11 December 2027. Energy labelling has to be visible in distance selling. These are not features — they are obligations that a theme can either help with or ignore.

The one rule that governs every block in this chapter

Section titled “The one rule that governs every block in this chapter”

The theme displays. It never computes, completes or invents.

No block derives an energy scale from an energy class, fills in a missing address, guesses a manufacturer role, or assumes a load factor for a power calculation. Where the merchant has not maintained a value, nothing is shown. An invented compliance figure is worse than a missing one, because it looks like a checked one.

The practical consequence: a store without the data model shows none of these blocks. That is not a fault. Each block simply renders nothing and, in the theme editor, tells you which field it is missing.


7a.1 Before anything renders — the data model

Section titled “7a.1 Before anything renders — the data model”

A Shopify theme cannot ship metafield or metaobject definitions. Shopify only allows a metaobject setting to point at standard definitions, and there is effectively one of those. Everything in this chapter therefore lives where somebody created it: in your store, under Settings → Custom data.

The full set is 8 metaobjects and 43 metafields.

Metaobjects (Settings → Custom data → Metaobjects)

Section titled “Metaobjects (Settings → Custom data → Metaobjects)”
MetaobjectWhat it isUsed by
spec_fieldOne specification value — key, label, group, unit, plus three switches that decide where it appearsproduct-specs, product card, comparison, filters
spec_sheetA named, ordered list of spec_field entries. A product shows exactly its sheetproduct-specs
compat_targetOne compatibility target — device, vehicle, printer, standardproduct-compat, Compatibility finder
documentA document with title, kind, language, version and dateproduct-files
economic_operatorManufacturer or EU responsible person with a full postal addressproduct-gpsr
product_questionA question with its answer, optionally tied to a spec keyproduct-qa
spare_partPart number, name, price, availability, toolsproduct-parts
repair_stepStep number, title and instruction linesproduct-repair

spec_field carries three booleans: show_in_card, comparable and filterable. That is why no block in this chapter has a “which fields to show” picker — the table, the product card and the comparison all read the same three switches. Add a field once, tick where it should appear, and every surface follows.

If the theme carried its own field picker next to those flags, you would be maintaining the same decision in two places, and the simple-maintenance argument this theme makes would be gone.

Metafields (Settings → Custom data → Products)

Section titled “Metafields (Settings → Custom data → Products)”

Five namespaces:

NamespaceHoldsCount
specsthe specification values themselves plus sheet and questions23
complianceenergy label, EPREL, durability/repairability index, GPSR operators, warnings, support and repair dates15
docsfiles — the product’s documents1
compattargets — what the product fits1
partsitems — the spare-part catalogue1
reviewsrating, rating_countShopify’s own namespace, written by any compliant review app2

The namespaces for specs and compliance are configurable once, theme-wide, under Theme settings → Layout:

SettingWhat it does
🔧 Compliance metafield namespace (compliance_ns)One namespace for the product card and both compliance blocks. ✅ Default compliance. The keys inside it are fixed.

⚠️ The second step people forget: Search & Discovery

Section titled “⚠️ The second step people forget: Search & Discovery”

Definitions alone do not make a value filterable. To get a spec onto collection and search pages as a filter, release it in Shopify’s own free Search & Discovery app under Filters → Add filter. The same applies to the category attributes Shopify creates by itself.

Nothing breaks without it: the theme checks which filters are actually released and only links a value when it finds one. An unreleased value simply renders as text.

WhatNeeds release?
Availability, price, product type, vendor, variant optionsNo — built in
Your own metafields (specs.*, compat.targets)Yes
Shopify’s category attributesYes

The specification table. Reads the product’s spec_sheet and renders its fields as a grouped table.

SettingWhat it does
🔧 Heading (heading)✅ Default “Specifications”.
🔧 Metafield (sheet_key)Which product metafield points at the specification sheet. ✅ Default specs.sheet. The fields, their labels and their groups live in the data set, not here.
🔧 Additional metafields (extra_keys)Comma-separated namespace.key list, appended after the sheet. Meant for Shopify’s own category attributes. ✅ Default empty.
🔧 Collection for the filter link (filter_collection)Handle of the collection that filterable values link into. ✅ Default all.
🔧 Show group headings (show_groups)Render the group value of each field as a sub-heading. ✅ Default on.

Behaviour worth knowing:

  • Empty fields are skipped. A product that does not carry a value produces a blank, and a table with empty rows would be worse than no table.
  • Unit types format themselves. weight, power, dimension and volume metafields already return “38.5 W” complete with unit. unit_override on the spec_field beats both.
  • List values are joined. A list.single_line_text_field renders as “HDMI 2.1 · DisplayPort 1.4 · USB-C”, not run together.
  • A filterable value becomes a link into the collection named above, pre-filtered to that value — but only if the filter is released in Search & Discovery.

What the product fits: devices, vehicles, printers, standards. One field carries all four, because the shape of the answer is the same.

SettingWhat it does
🔧 Heading (heading)✅ Default “Compatible with”.
🔧 Heading size (heading_size)h2 / h3 / h4. ✅ Default h3.
🔧 Group by category (show_groups)Group entries by the category field of each compat_target. ✅ Default on.
🔧 Note below the list (note)Optional — for example a hint that the list is not exhaustive. ✅ Default empty.
🔧 Metafield with the targets (targets_key)Advanced. ✅ Default compat.targets — a list of compat_target metaobjects.
🔧 Collection for the filter link (filter_collection)Advanced. ✅ Default all.

The reverse view — “show me everything that fits my device” — is the Compatibility finder section, covered in chapter 10.


7a.4 EU energy & durability (product-eu-label)

Section titled “7a.4 EU energy & durability (product-eu-label)”

Energy efficiency class, the scale it sits in, the EPREL link, and the French durability / repairability indices.

SettingWhat it does
🔧 Heading (heading)✅ Default “Energy and durability”.

Everything else is data. That is deliberate — three constraints shape this block:

  1. Never derive, only display. The scale is not inferred from the class (“F, so probably A–G”). The same letter sits in a different scale depending on the product group. If the scale is missing, it stays missing. Regulation (EU) 2017/1369 requires the class and the range of the scale wherever the label itself cannot be shown — which is exactly why the range is its own maintained field.
  2. The official label is a file, not a drawing. The arrow graphic is regulated artwork; EPREL supplies it. The theme prints the class and links the file. The colour bar under it is deliberately a bar and not an arrow — it should look like what it is.
  3. Liquid cannot call EPREL. The link is built from the two maintained fields eprel_group and eprel_id.

The durability index is not a nice-to-have. France’s indice de durabilité has applied to televisions since 8 January 2025 and to washing machines since 8 April 2025, and the regulation requires it on every purchase page, in the same size as the price. That is why the value also appears on the product card.

EPREL numbers, GTINs, EANs, GS1 and UDI codes sit in a densely populated number space. An invented number either hits a real registration — which belongs to somebody else — or collides with one. There is practically no third outcome.

For demo content: either no identifier, or one of your own. Never a plausible-looking one.


Turns specs.power_draw into a yearly and monthly electricity cost the buyer can adjust.

SettingWhat it does
🔧 Heading (heading)✅ Default “Running cost”.
🔧 Electricity price per kWh (price_default)Starting value in the shop currency. Buyers can change it. ✅ Default 0.30.
🔧 Hours per day (hours_default)Starting value. ✅ Default 8 — a working day, not around the clock.

It says what it is computing. power_draw is the maximum power draw, and the block states so under the result. There is deliberately no invented load factor: a made-up “typical usage is 40 %” would turn a measured figure into a marketing one.

Two details that matter in practice:

  • The price field is a text input with inputmode="decimal", not a number input, so it accepts 0,30 as well as 0.30. A number input rejects the comma silently depending on locale.
  • Money is formatted through the theme’s single money formatter, which follows shop.money_format. It is never assembled in JavaScript — '$' + (cents/100).toFixed(2) produces $3500.00 where the server produces $3,500.00, in the same window.

7a.6 Repair and spare parts (product-repair)

Section titled “7a.6 Repair and spare parts (product-repair)”

Repairability index, spare-parts window, repair manual, and — expandable on the page — the actual repair steps.

SettingWhat it does
🔧 Heading (heading)✅ Default “Repair and spare parts”.
🔧 Show the guarantee note (show_guarantee)✅ Default on. The EU Right to Repair Directive has applied since 31 July 2026, so this is a statement of law, not a product claim.

The index bands are 8 / 6 / 4 / 2repairability_index ≥ 8 renders as band a, ≥ 6 as b, ≥ 4 as c, ≥ 2 as d, below that e. ⛔ These are not the 9 / 7 / 5 / 3 bands of the durability index in 7a.4. Two different scales, two different colour thresholds.

⭐ Why the repair steps are visible and not just in the PDF

Section titled “⭐ Why the repair steps are visible and not just in the PDF”

The steps from compliance.repair_steps render on the page inside an expandable <details> block — and they are marked up as HowTo structured data.

That order is not decoration. Google forbids marking up content a reader of the page cannot see. The steps originally existed only inside a downloadable PDF, which meant the strongest argument this kind of store has was the one thing nobody saw. Making them visible was the precondition for the markup, and it turned an SEO task into a better product decision.

One source feeds three consumers: the PDF, the metaobjects, and the page.


The spare-part catalogue: part number, name, price, availability and the tools needed.

SettingWhat it does
🔧 Heading (heading)✅ Default “Spare parts”.
🔧 Show the tools column (show_tools)Which tool, and how the part fits. ✅ Default on — it is the part of a repair that decides whether somebody attempts it.

Not every part has a price. Soldered sockets and bonded assemblies carry “not available separately” instead of a figure, and the block renders that as written. A catalogue that prices everything implies everything is replaceable.


How long the product receives security updates, derived from compliance.support_until.

SettingWhat it does
🔧 Heading (heading)✅ Default “Security updates”.
🔧 Show the legal note (show_note)✅ Default off.

Three states, computed from the date:

RemainingRenders as
more than 365 days”still N years”
1–365 days”still N months”
past”ended”

⛔⛔ Why this note defaults to off and the repair note defaults to on

Section titled “⛔⛔ Why this note defaults to off and the repair note defaults to on”

The Cyber Resilience Act, Regulation (EU) 2024/2847, applies in full from 11 December 2027. The Right to Repair Directive has applied since 31 July 2026.

A notice that ships switched on has to be true today. One of these is already law and one is not yet, so one default is on and the other is off. When the CRA takes effect, turn it on.


Manuals, declarations of conformity, data sheets, dimensional drawings.

SettingWhat it does
🔧 Heading (heading)✅ Default “Downloads”.
🔧 Metafield (metafield)Which product metafield holds the files. ✅ Default docs.files.
🔧 Label (label)Only used where an entry brings no title of its own; otherwise the file name is shown. ✅ Default empty.
🔧 Appearance (style)link / button. ✅ Default link.
🔧 Open a preview first (preview)Show the preview Shopify generates, with open and download from there. ✅ Default on.

You enter namespace.key and the block works out what is behind it:

ShapeResult
file_referenceone file
list.file_referenceseveral files
metaobject_referenceone document — title, file, kind, language, version, date
list.metaobject_referenceseveral documents
url / list.urla link to somewhere else

Images get a viewer with zoom and pan — mouse wheel, double-click, two fingers, three buttons and the keyboard — plus a high-resolution version fetched only on the first zoom. That is what makes a dimensional drawing usable: at 1200 px a plan scaled to window width just gives you bigger pixels.

The download really downloads. A download attribute on a cross-origin link is ignored by the browser, and the Shopify CDN is a different origin from the shop. The preview window therefore downloads through a blob, where the attribute does apply.


Manufacturer, EU responsible person, and safety warnings.

SettingWhat it does
🔧 Heading (heading)✅ Default “Product safety”.

This is the block with the widest reach and the smallest effort. The General Product Safety Regulation (EU) 2023/988 has applied since 13 December 2024 to every consumer product, not only electronics. In distance selling the following must be visible before the contract is concluded:

  • the manufacturer’s name and postal address, plus an electronic address
  • where the manufacturer sits outside the EU, the same details for the responsible person in the Union
  • warnings and safety information

The block reads two economic_operator metaobjects and one rich-text field. It fills in nothing: no address is completed, no role is derived. What the merchant has not maintained does not appear.


Technical questions and their answers, from specs.questions.

SettingWhat it does
🔧 Heading (heading)✅ Default “Questions about this product”.
🔧 Open the first question (first_open)✅ Default off.

A product_question can carry a spec_key. Where it does, the question is tied to that specification field and the field’s label is shown as its subject. ⭐ The label comes from spec_field.label and is therefore already translated — which is why it never has to be repeated inside the question text.


Stars and review count from reviews.rating and reviews.rating_count.

SettingWhat it does
🔧 Text alignment (alignment)left / center / right. ✅ Default left.
🔧 Size (size)xs / sm / md / lg. ✅ Default sm.
🔧 Show the number (show_value)✅ Default on.
🔧 Show the review count (show_count)✅ Default on.

reviews is Shopify’s own namespace, and every compliant review app writes into it — so this block works with the app you already have, without an integration.

Partial stars are two rows, not half glyphs. The filled row is clipped to the exact percentage, so 4.6 / 5 renders as exactly 92 %.

⚠️ A rating metafield returns an object (rating, scale_min, scale_max), not a number. The block reads the parts separately so the maximum is honoured rather than assumed to be 5.

Invented consumer reviews are prohibited under the EU Omnibus Directive. If you are populating a demo store, the demo-data tooling that ships with the theme’s development scripts always has a matching removal path — use it before the store does real business.


7a.13 Back-in-stock notice (product-notify)

Section titled “7a.13 Back-in-stock notice (product-notify)”

A short form that lets a visitor be told when a sold-out variant returns. Posts through Shopify’s own {% raw %}{% form 'contact' %}{% endraw %}, so it needs no app and no external service.

SettingWhat it does
🔧 Heading (heading)✅ Default “Sold out — tell me when it is back”.

The block is always rendered and hidden rather than conditionally rendered. What is not in the DOM cannot be revealed when the visitor switches to a sold-out variant — the form has to exist before it is needed.

Place it where the buy button is: on a sold-out variant the buy button goes away and this takes its place.


The order below is thematic, not historical — it walks the buyer from “what is it” through “what does it cost me to own” to “what happens if it breaks”:

vendor · title · rating · price · variant_picker · buy_buttons · notify ·
pickup · description ·
specs · compat · eu-label · power-cost · repair · parts · support ·
files · gpsr · qa · share

Stars sit next to the name. The back-in-stock form sits where the buy button was. Then the four lifetime layers in the order a buyer thinks about them — energy → running cost → repair → spare parts → updates. Then documents, safety, questions.


7a.15 What the law requires, and from when

Section titled “7a.15 What the law requires, and from when”
RuleIn forceBlocks
Energy labelling — Regulation (EU) 2017/1369in force; label must be visible in distance sellingproduct-eu-label
French durability index (indice de durabilité)TVs 8 Jan 2025 · washing machines 8 Apr 2025; must appear on every purchase page at price sizeproduct-eu-label, product card
GPSR — Regulation (EU) 2023/98813 December 2024, every consumer productproduct-gpsr
Right to Repair Directive31 July 2026product-repair, product-parts
Cyber Resilience Act — Regulation (EU) 2024/284711 December 2027 (full application)product-support
Omnibus Directive — no fabricated reviewsin forceproduct-rating, product-qa

⚠️ This table is an orientation, not legal advice. Which rules bind you depends on what you sell and where. Where a date decides whether a notice is switched on by default, this manual says so at the block.


7a.16 What happens when the data is missing

Section titled “7a.16 What happens when the data is missing”

Nothing breaks, and nothing is faked. Per block:

BlockWithout its data
product-specsrenders nothing; individual empty fields are skipped inside an otherwise complete table
product-compatrenders nothing
product-eu-labelrenders nothing; a missing scale is simply absent next to the class
product-power-costrenders nothing when specs.power_draw is unset
product-repairrenders nothing; the steps <details> appears only where steps exist
product-partsrenders nothing; a part without a price shows its availability text instead
product-supportrenders nothing when compliance.support_until is unset
product-filesrenders nothing
product-gpsrrenders only the operators and warnings that are maintained
product-qarenders nothing
product-ratingrenders nothing when reviews.rating is unset
product-notifypresent but hidden while the variant is in stock

In the theme editor each block names the field it is missing, so an empty product page tells you what to fill in rather than leaving you guessing.

See also: Chapter 7 — Product sections · Chapter 10 — Marketing & interaction sections for the Compatibility finder and Product comparison · Chapter 13 — SEO & GEO for the structured data these blocks emit.