Skip to main content
Copy for LLM

Price

A locale-aware price display component for e-commerce and SaaS interfaces. Supports currency formatting, strike-through compare-at prices (RRP / UVP / MSRP), unit prices (Grundpreis) for EU price-marking compliance, delta indicators, and size variants.

Basic Usage

Simple price
$29.99

Compare-At Price (RRP / UVP / MSRP)

Show the previous or recommended retail price as a strike-through alongside the current price. The strike-through value answers the question "what was this before?":

  • RRP — Recommended Retail Price (UK)
  • UVP — Unverbindliche Preisempfehlung (Germany)
  • MSRP — Manufacturer's Suggested Retail Price (US)

The base prop carries this comparison value. It does not mean "base price" in the unit-price sense — see Unit Price (Grundpreis) below for that.

Sale price with strike-through
Previous price $29.99 $19.99 Previous price €79.00 €49.00

From Price

A product whose variants cost different amounts shows the lowest of them, and without a word that amount reads as the price of the product. from writes "from" before the amount, in the application's language: "from €19.99", and "ab 19,99 €" on a German page. It is visible text, and a screen reader reads it with the amount. Beside a compare-at price the struck amount comes first, so the pair reads "Previous price €24.99, from €19.99".

The cheapest of several variants
Previous price €24.99 from €19.99

Unit Price (Grundpreis)

For pre-packaged goods sold by weight, volume, length, or area, EU and UK price-marking law requires the per-unit price to be displayed alongside the selling price. In Germany this is the Grundpreis per PAngV § 4; in the UK it is the unit price per the Price Marking Order 2004; the EU baseline is Directive 98/6/EC.

Pass unitPrice (numeric, same currency as amount) and unitMeasure (the reference unit label) — the component renders them as (€8.99 / L) next to the main price, in the same currency, in the same field of vision.

Bottle of olive oil — €4.49 / 500 ml
€4.49 (€8.98 / L)
Bag of coffee beans — €12.99 / 250 g
€12.99 (€51.96 / kg)
Sale price + unit price combined
Previous price €4.99 €3.49 (€6.98 / L)

Reference units are jurisdiction-dependent. Germany: per kg, L, m, m² or m³; loose goods sold by weight or volume may use 100g / 100ml where that is the custom (PAngV § 5). The EU directive names the same five units and lets a member state keep a unit it customarily uses for a product. Great Britain uses the same five units, or the price per item for goods sold by number, under the Price Marking Order 2004 as amended in 2024. The US has no federal unit-price law; several states and the District of Columbia require unit pricing in retail, New York and Massachusetts among them, and NIST's uniform unit-pricing regulation allows metric and US units (oz, lb, fl oz) alike. The component does not validate the unit string — pass whatever your jurisdiction requires.

More Decimals Than the Currency

A price per piece can be smaller than the currency's smallest unit: a screw at 0.045 € each, a price list kept to four decimals. max-precision shows up to that many decimals, never fewer than the currency's own, and drops trailing zeros back to them. The previous price and the unit price beside the amount take the same digits.

Prices per piece with up to four decimals
0,045 € 0,0475 € 12,50 €

A currency without minor units, such as the yen, shows decimals only where the amount has some. Without the prop a price shows its currency's digits.

Every amount is rounded half away from zero, the way a till and an invoice round: 0.125 in euros reads 0,13 € and -0.125 reads -0,13 €.

Delta Indicator

Attach a percentage or absolute change indicator:

Price with delta (percent)
$24.99 -20% $34.99 +10%
Price with absolute delta
$120.00 -30

The delta is written the way the active locale writes numbers, like the amount beside it: -12,5 % in German and -12.5% in English. An absolute delta is a plain number in the same notation, without a currency.

Size Variants

All size variants
$9.99 $9.99 $9.99 $9.99 $9.99

Fitting a Narrow Column

A long amount in a narrow column, a cart's total or a price in a currency with many digits, can shrink to fit its line with fit instead of breaking or running out. The struck price, the word "from" and the amount shrink together and keep one size; the change, the suffix and the unit price beside them keep theirs. fit alone uses the --text-wk-fit-floor token, three quarters of the price's size, and a length such as fit="0.5rem" sets a floor of its own. Below the floor the price runs past its column rather than break. How the fitting works and what it costs is on the Fit Text page.

An amount fitted to two column widths
€1,234,567.89
€1,234,567.89

Minor Units (Cents)

Pass amounts in minor units (cents) and let the component convert:

Minor units conversion
$29.99

With Suffix Slot

Add recurring interval text or other context:

Price with suffix
$12.00 / month

Full Sale Example

Complete sale price
Previous price $79.99 $49.99 -38% / year

Props

Prop Type Default Description
amount int|float|string null The price amount to display: a number, or a numeric string such as "19.99" as a decimal cast stores it. Without one, null or an empty string, nothing is drawn
currency string 'USD' ISO 4217 currency code
locale string app()->getLocale() Locale for number formatting
base int|float|string null Compare-at / RRP / UVP / MSRP price (shown as strike-through)
unitPrice int|float|string null Per-unit price (Grundpreis) — required by EU / UK price-marking law for goods sold by weight / volume / length / area
unitMeasure string null Reference unit label paired with unitPrice (e.g. L, kg, 100g, 100ml, m²)
delta int|float|string null Change indicator value
delta-format string 'percent' Delta format: percent or absolute
size string 'md' Size variant: xs, sm, md, lg, xl
minor-units bool false When true, divides amount / base / unitPrice by 100
from bool false The amount is the lowest of several, the cheapest variant's: writes "from" before it, in the application's language — see From Price
max-precision int|null null The most decimals to show, for a price that has more than its currency, such as a price per piece. Never fewer than the currency's own, and trailing zeros drop back to them — see More Decimals Than the Currency
fit bool|string|null null Shrinks the price down to a floor so it fits its line; the struck price, "from" and the amount shrink together. true for the --text-wk-fit-floor token, or a length such as 0.5rem — see Fitting a Narrow Column
scope string|null null Scoped personalization name

Slots

Slot Description
suffix Text after the price (e.g. "/ month")

Accessibility

  • Every part is read from the content itself — the root <span> carries no aria-label. ARIA prohibits aria-label on an element with no role, so a name placed there is not required to reach assistive technology at all
  • Strike-through compare-at price uses <del> element for semantic meaning, prefixed with a visually-hidden "Previous price" — <del> maps to role="deletion", which screen readers do not announce by default, so without the prefix the two amounts read as unrelated
  • <bdi> wraps formatted values for correct RTL rendering
  • The word from writes is visible text before the amount, read with it, not a label on the wrapper
  • Unit price is read out like any other visible text; it is deliberately not aria-hidden, because it is the figure EU / UK price-marking law requires the reader to get

Keyboard Interaction

This component is purely presentational and does not respond to keyboard input.

Pitfalls

  • Pass the raw number, never an already-formatted string. Pass :amount="19.99", and the component formats it with the active locale's decimal and thousand separators. A string that is no number, "19,99" with a decimal comma, "1.234,56" or a word such as "on request", is refused while you develop, and in production the price is left out rather than shown as a wrong amount, since PHP would read "19,99" as 19 and a word as 0. A refused base, unitPrice or delta leaves out only itself. One spelling cannot be caught: "1.234", a thousand in German writing, is a number to PHP and reads as 1.234. Convert a localized figure to a number before you pass it.
  • No amount draws no price, and a zero draws 0.00. null or an empty string, a price on request for example, renders nothing rather than a 0 nobody gave, and it is not reported, because a catalog has such products. Pass 0 for something that is free.
  • Without PHP's intl extension, an amount carries the currency code instead of a symbol. WireKit does not require the extension. Without it, the amount is written with English separators and the ISO code after it, 1,234.56 EUR, and the delta the same way, because the symbols, where they go and each language's separators come from the extension. Install intl to render 1.234,56 € in German.

Design Tokens

Token Used for
--font-wk-sans Price font family
--font-wk-heading-weight Amount + currency weight
--text-wk-xs / --text-wk-sm / --text-wk-md / --text-wk-lg / --text-wk-xl Font size per size prop
--color-wk-text Amount + currency color
--color-wk-text-muted Strike-through base price + suffix
--color-wk-success-text Negative-direction delta (savings)
--color-wk-danger-text Positive-direction delta (price increase)
--text-wk-fit-floor The floor of a price with fit and no floor of its own, 0.75em

Updated in WireKit v2.68.0 (2026-10-16)

Was this page helpful?

Thank you for your feedback!

Voting requires cookies or local storage. What we store