Skip to content
BolderBolder Developers
Esc
↑↓navigate↵open⌘Jpreview
On this page

Forms & Content

Submitting to a shop's contact forms, and reading the small set of content pages headless shops can still show.

Forms

storefront.forms lets a headless shop submit to a Bolder contact form (the same forms you build in the shop admin) without any Bolder-hosted markup. Useful for a contact page or feedback form on a statically-generated site, where the form’s HTML needs to be part of the static page for SEO but the submission still needs to reach the shop’s contacts.

get(slug, fn)

Fetches a form’s field definitions so you can render your own inputs.

storefront.forms.get('contact', (err, form) => {
  if (err) return console.error(err)

  console.log(form.title, form.message) // form.message is the form's body/intro text
  form.contactFields.forEach(field => {
    // field: { key, name, field_type, required, value, options? }
  })
  form.customFields.forEach(field => { /* same shape */ })
})

submit(form, data, fn)

Submits data collected from your own form UI. Pass the form object returned by get() — submit uses it to sort your flat data object into the contact_fields/ custom_fields split the backend expects, keyed by each field’s key.

storefront.forms.get('contact', (err, form) => {
  myForm.addEventListener('submit', e => {
    e.preventDefault()

    storefront.forms.submit(form, {
      name: myForm.name.value,
      email: myForm.email.value,
      message: myForm.message.value, // a custom field, e.g.
    }, (err, result) => {
      if (err) return showErrors(err.errors)
      showSuccess(form.sentMessageText)
    })
  })
})

On validation failure err is { success: false, errors: [{ field, messages }] }.

Content JSON endpoints

A headless shop 404s on every server-rendered page — there’s no theme to render it with — except for a small set of shop-authored/-configured content pages that are also served as plain JSON, so a headless integration can still show them: storefront.promos, plus storefront.plans and storefront.points when the shop has them enabled.

storefront.promos.get(function(err, promos) { renderPromos(promos) })
Endpoint SDK Mirrors Returns
GET /plans.json storefront.plans.get(fn) /plans Array of membership plans: { id, name, description, url, images, attributes, subscription_fees }. Each subscription_fees entry has { id, setup_fee, renewal_fee, payment_interval, interval_label, variant_id } (amounts are numeric, smallest-currency-unit).
GET /promos.json storefront.promos.get(fn) /promos Array of the shop’s visible/eligible promotions — same shape as GET /promos/:id.json: { id, discount, discount_type, name, automatic, full_discount, ... }.
GET /policies/points.json storefront.points.get(fn) /policies/points The shop’s points-club policy config (naming, earn/expiration rules, an example earn calculation, contact channel) — not a customer’s balance, see buyer_points under Customer Console for that. {} if the shop has the points-club addon but no settings configured.

storefront.plans and storefront.points only exist when /shop.json reports the shop has them enabled (plans_enabled/points_enabled) — a shop without membership plans has no storefront.plans at all, rather than one that 404s when called. storefront.promos is always present. All three are unauthenticated, public reads — no storefront.authAjax needed.

Was this page helpful?