Price Snippet With a Bundle 'Value' Metafield Line and Opt-Out Labelled Price Links
Dawn's price snippet on Nudestix, extended in two small ways: a product metafield adds a "worth" line beside a kit's price, and the price text becomes a labelled link to the product unless the caller says otherwise.
Shopify has no field for what a kit is worth bought as separate products, and Dawn's price snippet renders the price as plain text. On Nudestix we extended price.liquid so a product metafield adds a "(… Value)" line beside the price, and so the price itself renders as a link with a generated accessible name and a ?from=card-price marker — on by default, opted out by the two callers where a link would be wrong.
The Problem
Shopify's product model carries two prices, price and compare_at_price, and nothing else. A compare-at price is a was price for the same item. It can't say what a kit of five products would cost as five purchases, which is the number a kit is sold on. That figure has to live somewhere the theme can read, and the price component has to know how to show it.
The second problem sits in the same snippet. Dawn renders a price as a <span> — text a shopper reads but can't act on — and relies on the card's title and image for the way in. On a product card that's a reasonable default. On a grid where the price is the thing a shopper's eye lands on, it means the most-noticed element on the card does nothing when it's clicked or focused.
The Constraint
Shopify offers no "value" concept, so the figure lives in a product metafield, product.metafields.sf_product_meta.product_value, and the snippet can only display what's been entered there.
The snippet is shared. price.liquid is rendered from twelve files on this theme — the product sections, the featured-product section, predictive search, the kit modal and every card snippet — so a change to how the price renders reaches all of them at once. Two of those callers can't take a link: predictive search already wraps each result in an anchor, and a nested anchor isn't valid HTML; the kit modal prices a set inside its own buy control. So the link couldn't be assumed. It had to be a render argument with a default, and the default had to suit the majority of callers, which are cards.
The theme base is Dawn 6.0.2, so this is a modification of Dawn's snippet rather than a component of our own.
What We Built
price.liquid reads product.metafields.sf_product_meta.product_value into a local variable at the top of the snippet. When it's set, two things happen. The outer .price element gains a price_with_value class, which component-price.css uses to lift a height cap on small screens so the extra line has room. And inside the regular-price block, directly after the price, a <span> renders the figure through money_without_trailing_zeros followed by the word "Value", in parentheses. Without the metafield, no class and no line.
The link is governed by a show_link argument. The snippet only treats it as off when a caller passes show_link: false explicitly; absent or anything else, it's on. When on, the regular price renders as an <a> with Dawn's full-unstyled-link class, tabindex="0", an href of product.url | within: collection followed by ?from=card-price, and an aria-label assembled in Liquid: the last segment of product.url, hyphens replaced with spaces and capitalized, then the words "Price of", then the formatted price. Both the label and the visible price run through strip_html, so the <span class="money"> markup that Shopify's money format wraps around a figure never lands inside an attribute or the link text. When the argument is off, the same price renders as a <span> with the same classes minus the link one.
Because the href goes through within: collection, a card on a collection page links to the product at its collection-scoped path, so the product page's breadcrumb and back-navigation know which collection it came from. The ?from=card-price suffix rides along as a marker for whatever reads the query string downstream.
Why This Way
A link with an explicit accessible name gives keyboard and screen-reader users a way to act on the price without adding a visible control to the card. The label reads as product, price of amount rather than as a bare figure, so a screen reader listing the card's links says which product and how much. The ?from=card-price marker is there so a click on the price is distinguishable, in analytics, from a click on the title or the image.
Defaulting the link to on was a decision about the callers. Ten of the twelve are cards or product sections; the two that can't take a link are the ones that say so. Putting the opt-out on the minority keeps the common call site a one-liner.
Two costs come with that. Any future caller gets a link unless its author knows to pass show_link: false, so the default is also a trap for the next card snippet. And the value line lives inside the regular-price block, which the stylesheet hides when a product is on sale — the kit modal draws its own value line above the snippet for that case, a second place to maintain the same thing.
Implementation Notes
- Rendered from twelve files:
featured-product,main-product,main-product-bundle,main-single-product,mainproduct-bundleandpredictive-searchamong the sections, plusbundle-kitsand five card snippets. show_linkis on unless a caller passesshow_link: false; the snippet normalizes anything else to true, so an omitted argument and atruebehave the same.- The two opt-outs are
predictive-search.liquid, where each result is already wrapped in an anchor, andbundle-kits.liquid, where the kit modal renders the price inside its own buy control. - The
aria-label's product name is derived from the last segment ofproduct.url— hyphens to spaces, first letter capitalized — rather than fromproduct.title. - The visible price and the label are both passed through
strip_html, so the money format's wrapping<span>is removed before either lands in the anchor. - The value line is formatted with
money_without_trailing_zeros, so a whole-dollar value renders without a.00. component-price.csstargets.price_with_valueonly at the mobile breakpoint, to release amax-heightthat would otherwise clip the second line.
Edge Cases
- No value metafield on the product: no
price_with_valueclass and no value line. show_badgesnot passed: theprice--sold-outandprice--on-saleclass hooks still switch, but no "Sale" or "Sold out" tag is emitted.- On a product that's on sale, the regular-price block — and the value line inside it — is hidden by
component-price.css, so the value line is a full-price treatment. The kit modal renders its own value line to cover the sale case. - A product rendered outside any collection:
within: collectionyields the plain product URL, and the marker is still appended. - No
unit_price_measurementon the variant: the unit-price block is emitted with Dawn'shiddenclass rather than omitted.
Platform Primitives Used
- Metafields — one product metafield supplies the value line, formatted through
money_without_trailing_zeros; its presence also toggles theprice_with_valueclass. - Liquid snippets — a single snippet with render arguments, called from twelve files, where one argument decides whether the price is a link or a span.
Where It Runs
Wherever the theme prices a product: the product page and its bundle and single-product section variants, every card on collection listings and in the featured-collection sections that reuse those cards, and the predictive search results. The value line shows on kits that carry the metafield; the price links on every card that doesn't opt out.
What This Demonstrates
- Fixed bundles and kit merchandising — the primary capability: a kit's "worth" is a field the price component knows how to display, so a set reads as a product with a value rather than as a discount.
- Metafield-driven PDP content blocks — the value is a product metafield the price component reads, so which kits show a value, and what it says, is data rather than markup.
How We Know
One snippet, roughly 150 lines, read from the theme and set against Dawn 6.0.2, plus the twelve files that call it. The value line and the linked price were both confirmed rendering on the live storefront's kit listings. Documented from the code; no client-side record of the decision survives. What the snippet does is verifiable; the reasons above are our reading of it.
Related Builds
- "Save With Sets": shade-selectable kit contents on the component product's page — same storefront: the kit modal that opts out of the price link and draws its own value line from the same metafield.
- Product card with award badges, per-variant content payload and per-card structured data — same storefront: the card snippet that is this snippet's most-rendered caller.
- Variant-aware price snippet with percentage + value savings badge — LUS Brands, on Dawn 15.4.1: the same Dawn snippet extended in the other direction, where the argument chooses the variant rather than the link.
- A second product template whose add-to-bag switches between one cart line and several — same storefront: the bundle product section that calls this snippet on the kit's own page.
The Buy-vs-Build Question
Bundle apps carry their own price display and their own "value" copy, rendered by the app on the app's terms. Extending the theme's price snippet keeps a kit an ordinary product whose value line is a metafield and whose price is the theme's own markup. Where that trade sits is argued at fixed bundles and multipacks: buy or build?.
Provenance & Evidence
- Client: Nudestix — nudestix.com
- Surfaces: Product detail page, collection listing, search
- Templates served: every template that renders a product card or a product section
- Complexity: Low — one snippet, roughly 150 lines, twelve callers
- Attribution: Deploi-modified vendor. Built on top of Dawn 6.0.2;
price.liquidis Dawn's snippet and this is our modification of it. The three changes this page describes — the value line, theshow_linkargument and the labelled anchor — are ours. - Status: Live, verified 2026-09-07
- Evidence: the snippet and its twelve callers, read from the theme; the value line and the linked price confirmed on the live storefront
- Confidence: Moderate — documented from the code; no client-side record of the decision survives
- Not claimed: any site-level accessibility statement; this is one component's link and label
- Primary capability: Fixed bundles and kit merchandising
Ready to Make the Most-Looked-At Thing on Your Card Do Something?
If your kits are sold on what they're worth and your price is a span, both fixes live in one snippet. Contact us today and we'll look at what your price component is rendered from — and where it shouldn't be a link.