Home
Examples

Preorder widget & button

Copy-paste preorder examples — drop-in widget element, one-call renderer, a hand-built button, and React.

Preorder widget & button

Sell a variant before it's in stock, with the right selling plan attached to the cart line. Examples use the Storefront SDK loaded with your shop + public Storefront API token (see the notify-me examples for the script tag).

Drop-in: the <stoq-preorder-widget> element

Badge + preorder CTA (with an optional notify-me fallback), zero JS. Because an HTML attribute can't carry a callback, the cart line comes back as a stoq:add-to-cart event — hand it to your cart:

<stoq-preorder-widget
  variant-id="43900910010503"
  product-id="7813090115847"
  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>

Attributes in, events out. Change variant-id and it re-renders itself. For a no-framework store, watch="select[name=id]" copies a <select>'s value into variant-id on change. Smaller pieces: <stoq-preorder-badge text="Preorder"> and the CTA-only widget.

One call: renderPreorderWidget

<div id="preorder"></div>
<script>
  window.addEventListener('stoq:loaded', async () => {
    const handle = await Stoq.renderPreorderWidget(
      { id: 43900910010503, availableForSale: false, currentlyNotInStock: true },
      { container: '#preorder', notifyMeFallback: true }
    )
    // handle.update(newVariant) on variant change; handle.destroy() to remove
  })
</script>

These render their own element into a container you own — the right model for headless (unlike the theme embed, which hijacks the theme's add-to-cart button).

Hand-built button (full control)

Use the primitives when you want your own markup:

const variant = { id: 43900910010503, availableForSale: false, currentlyNotInStock: true }
const cta = Stoq.client.preorderButtonFor(variant)   // null if no plan applies
if (cta) {
  buttonEl.textContent = cta.label                    // e.g. "Preorder now"
  buttonEl.addEventListener('click', async () => {
    // Payment-option picker (full vs partial) + quantity limits + acknowledgement:
    const confirmation = await Stoq.client.openPreorderModal({ variantId: variant, productTitle: 'Trail Runner' })
    if (confirmation) addToCart(confirmation.line)     // cart line with sellingPlanId attached
  })
}

Skip the modal and attach the plan directly:

const line = await Stoq.client.cartLineFor(variant, 1)
// { merchandiseId, sellingPlanId: 'gid://shopify/SellingPlan/…', quantity: 1 }

React / Hydrogen

import { StoqPreorderButton, StoqPreorderBadge } from '@artossoftware/stoq-sdk/react'

<StoqPreorderBadge variant={variant} />
<StoqPreorderButton variant={variant} />

Or drive your own UI with useStoqVariant(variant) (gives isPreorder / sellingPlanId / shipping text) and useStoqCartLine(variant). See Headless & Hydrogen.