Custom elements
Buy buttons, prices and product links in plain HTML, with no JavaScript of your own.
sorai-js defines three custom elements. They work in any HTML once
Sorai.init() has run.
<sorai-buy product-id="0199b0f0-0000-7000-8000-000000000021">Get the preset</sorai-buy>
<sorai-price product-id="0199b0f0-0000-7000-8000-000000000021"></sorai-price>
<sorai-price product-id="0199b0f0-0000-7000-8000-000000000021" currency="USD"></sorai-price>
<sorai-link product-id="0199b0f0-0000-7000-8000-000000000021">
<img src="/cover.jpg" alt="" />
<h3>Preset Senja</h3>
</sorai-link><sorai-buy>
A buy button. A click calls Sorai.checkout() for its product.
| Attribute | Description |
|---|---|
product-id | The product to buy. Required. |
price-id | The price to charge. Optional; without it, the store's default currency is used. |
With no content of its own, the element reads "Buy now".
<sorai-price>
Shows one of the product's prices, formatted in the store's locale.
| Attribute | Description |
|---|---|
product-id | The product to price. Required. |
currency | The currency to show. Optional. |
The price shown is the one in the element's currency, else in the
currency given to init(), else the product's first price. Sorai never
converts between currencies: a product with no price in the asked-for
currency shows a price it does have.
The element replaces its content only once the product has loaded. Put a fallback inside it, such as the price your page was built with, and it stays there if the request fails or the product is gone.
<sorai-link>
Links its content to the product's own page on the store, /p/{slug}.
| Attribute | Description |
|---|---|
product-id | The product to link to. Required. |
It is keyed on the product id, not the slug, so renaming a product's slug
never breaks a link: the runtime loads the product and builds the link from
whatever slug it has now. Once the product loads, the element moves its
content inside an <a>, so style it with the selector sorai-link a. An
unknown or inactive product, or a failed request, leaves the content as plain
markup and never links to a missing page.
The link is relative, so it belongs on a page of the store itself.
Putting them together
Use <sorai-link> for "see the product" and <sorai-buy> for "buy now". A
product card commonly carries both: one <sorai-link> around the cover and
the name, and a buy button beside it. Never put the button inside the link,
or a click on it would also follow the link.
<article class="card">
<sorai-link product-id="0199b0f0-0000-7000-8000-000000000021">
<img src="/cover.jpg" alt="" />
<h3>Preset Senja</h3>
</sorai-link>
<sorai-price product-id="0199b0f0-0000-7000-8000-000000000021">Rp 149.000</sorai-price>
<sorai-buy product-id="0199b0f0-0000-7000-8000-000000000021"></sorai-buy>
</article><sorai-price> and <sorai-link> share one request per product per page,
so a grid with a price and a link on every card loads each product once.
Events the elements send
<sorai-buy> and <sorai-price> send ViewContent for their product when
they appear on the page, once per product per page load: a price and a buy
button for the same product send one event between them. <sorai-link>
sends nothing, because the product page it opens sends its own.

