Every widget below is rendered by the real
@artossoftware/stoq-sdk in your browser, talking to a live store —
nina-and-kulfi-dog-toys.myshopify.com — with its public
Storefront API token. No server, no build step. Open the source under each card.
The product is a test variant (“Rabbit in a Carrot — Zero or less inventory”) that carries a STOQ preorder selling plan, so you can see real preorder + back-in-stock UI.
A single script tag with your shop domain and public Storefront token. It auto-registers the custom elements and fires stoq:loaded.
<script
src="https://cdn.jsdelivr.net/npm/@artossoftware/stoq-sdk@0/dist/stoq.min.js"
data-shop="nina-and-kulfi-dog-toys.myshopify.com"
data-storefront-token="<your-public-storefront-api-token>"
defer></script>
Zero JavaScript — the <stoq-preorder-widget> element renders the badge + preorder CTA for a variant and emits stoq:add-to-cart with the cart line (selling plan attached).
<stoq-preorder-widget
variant-id="49360289497368"
product-id="9564103180568"
notify-me-fallback></stoq-preorder-widget>
<script>
document.addEventListener('stoq:add-to-cart', (e) => {
// e.detail.line = { merchandiseId, sellingPlanId, quantity }
addToCart(e.detail.line) // your Storefront Cart API cartLinesAdd
})
</script>
For a sold-out variant with no plan, <stoq-notify-me> renders the back-in-stock signup. It hides itself when signups are off or the variant is in stock.
<stoq-notify-me
variant-id="49360289497368"
product-id="9564103180568"
label="Notify me when available"></stoq-notify-me>
Already have your own JavaScript? One Stoq.renderPreorderWidget(variant, { container }) call mounts the badge + preorder CTA into any element, wires click → modal → cart, and returns a handle you can .update() on a variant switch or .destroy(). It falls back to notify-me when the variant isn’t preorder-eligible.
const handle = await Stoq.renderPreorderWidget(
{ id: 49360289497368, availableForSale: false, currentlyNotInStock: true },
{
container: '#preorder-mount',
productId: 9564103180568,
badge: true,
notifyMeFallback: true,
onAddToCart(line) {
// line = { merchandiseId, sellingPlanId, quantity }
addToCart(line) // your Storefront Cart API cartLinesAdd
},
},
)
// later: handle.update(otherVariant) · handle.destroy()
The same data the elements use, read imperatively. This JSON is computed live from the shop’s published STOQ metafields.
window.addEventListener('stoq:loaded', async () => {
const variant = { id: 49360289497368, availableForSale: false, currentlyNotInStock: true }
const state = await Stoq.client.getVariantState(variant)
// → { isPreorder, sellingPlanId, shippingText, ... }
const cta = Stoq.client.preorderButtonFor(variant) // { label, ... } or null
const line = await Stoq.client.cartLineFor(variant, 1) // { merchandiseId, sellingPlanId, quantity }
console.log({
shop: Stoq.client.shop,
preorderEnabled: Stoq.client.preorderEnabled,
signupsEnabled: Stoq.client.signupsEnabled,
state, cta, line,
})
})