Stencil
Stencil Utils API
Stencil Utils reference

Stencil Utils Reference

Stencil Utils (opens in a new tab) is a utility library that contains the BigCommerce Stencil Events system and other methods that make building a theme with the Stencil framework a breeze.

These methods help you set up asynchronous requests to modify the customer’s cart or storefront view. By using this abstraction library, you can gain more-granular control over themes’ presentation. Use stencil-utils to:

  • Interact with the cart
  • Use getPage to return a template file.

Installing

As an ES6 module

  1. Run npm install @bigcommerce/stencil-utils to install the latest tagged version of stencil-utils for use with your theme.
  2. Import the library import utils from 'bigcommerce/stencil-utils'; in modules that depend on it.

Standalone

If you do not want to support ES6 modules, Stencil Utils can be included as a normal script:

  • Copy the bundled script from dist/stencil-utils.min.js to your theme.
  • Include the script in your HTML document
  • Access stencil utils from window.stencilUtils

api.js

Get page

getPage (opens in a new tab)

This method takes the form utils.api.getPage(url, options, callback).

ParameterTypeDescription/Usage
urlstringrequest URL. For example, /cart.php.
optionsobjectCan contain template, FormData (for POST methods) (opens in a new tab), params (for GET methods), and/or config.

The template option allows you to select a particular template, or an array of templates, for rendering one page. Each value must correspond to a file present in the theme's templates/components/ subdirectory.

The config option can be used to pass extra resources, corresponding to attributes that are valid in a page's front matter, as an object.
callbackfunctionAsynchronous function the subject method calls to handle any results.

The config argument works like front matter: it encapsulates JSON. For a usage example of config, see the Remote API Example.

In the following example from common/faceted-search.js, an updateView() method uses api.getPage() to refresh page content.

Example: getPage
updateView() {
  $(this.options.blockerSelector).show();
 
  api.getPage(urlUtils.getUrl(), this.requestOptions, (err, content) => {
    $(this.options.blockerSelector).hide();
 
    if (err) {
      throw new Error(err);
    }
 
    // Refresh view with new content
    this.refreshView(content);
  });
}

The Cornerstone theme uses the getPage method in the following contexts:

Get page by GraphQL

getPageByGQL (opens in a new tab)

This method takes the form utils.api.getPageByGQL(page, callback).

It allows you to render parts of a template using an inline GraphQL query, as shown in Front Matter Reference - GraphQL attributes.

ParameterTypeDescription/Usage
pagestringPresentation template to use for rendering one page; for example, pages/store-locator.
The template option allows you to select a particular template. The value must correspond to a file in the theme's templates/pages/ subdirectory.
callbackfunctionAsynchronous function the subject method calls to handle any results.
Example: getPageByGQL
utils.api.getPageByGQL('pages/store-locator', (err, response) => {
  if(err) {
    console.error(err);
  }
  // Server returns HTML template in the response, even if response is unsuccessful
  modal.updateContent(response);
});

Cart API

The following methods allow your theme to work with cart (opens in a new tab) contents in customized ways.

Get cart

getCart (opens in a new tab)

This method takes the form utils.api.cart.getCart(options, callback);.

ParameterTypeDescription
optionsobjectReturn product variant options.
callbackfunctionAsynchronous function the subject method calls to handle any results.
Example: getCart
utils.api.cart.getCart({}, (err, response) => {
  console.log(response);
  console.log(err);
});
 
utils.api.cart.getCart({includeOptions: true}, (err, response) => {
  console.log(response);
  console.log(err);
});

Get cart quantity

getCartQuantity (opens in a new tab)

Get a sum of the cart line item quantities. It takes the form utils.api.cart.getCartQuantity(options, callback);.

ParameterTypeDescription
optionsobjectReturn product variant options.
callbackfunctionAsynchronous function the subject method calls to handle any results.
Example: getCartQuantity
utils.api.cart.getCartQuantity({}, (err, response) => {
  console.log(response);
  console.log(err);
});
 
utils.api.cart.getCartQuantity({includeOptions: true}, (err, response) => {
  console.log(response);
  console.log(err);
});

Usage in Cornerstone

Item add

itemAdd (opens in a new tab)

The itemAddmethod allows your code to add an item to the cart, with options. This method takes the form utils.api.cart.itemAdd(FormData, callback);.

ArgumentTypeDescription/Usage
FormDataFormData (opens in a new tab) objectContains all details about the added item and its product options.

FormData example:
action: add
product_id: 123
attribute[123]: 321
qty[]: 1
callbackFunctionAsynchronous function call to handle the results

itemAdd is called at the head of the following example (from common/product-details.js) to populate the cart.

Example: itemAdd
utils.api.cart.itemAdd(this.filterEmptyFilesFromForm(new FormData(form)), (err, response) => {
  const errorMessage = err || response.data.error;
 
  $addToCartBtn
  .val(originalBtnVal)
  .prop('disabled', false);
 
  this.$overlay.hide();
 
  // Guard statement
  if (errorMessage) {
    // Strip the HTML from the error message
    const tmp = document.createElement('DIV');
    tmp.innerHTML = errorMessage;
    return showAlertModal(tmp.textContent || tmp.innerText);
  }
 
  // Open preview modal and update content
  if (this.previewModal) {
    this.previewModal.open();
    this.updateCartContent(this.previewModal, response.data.cart_item.id);
  } else {
    this.$overlay.show();
    // if no modal, redirect to the cart page
    this.redirectTo(response.data.cart_item.cart_url || this.context.urls.cart);
  }
});

Usage in Cornerstone

Item update

itemUpdate (opens in a new tab)

The itemUpdate method allows your code to update a specified cart item’s quantity. This method takes the form utils.api.cart.itemUpdate(itemId, qty, callback);.

ParameterTypeDescription/Usage
itemIdstringThe item’s ID
qtyintegerThe item’s quantity in the cart.
callbackfunctionAsynchronous function the subject method calls to handle any results.
Example: itemUpdate
cartUpdate($target) {
  const itemId = $target.data('cartItemid');
  const $el = $(`#qty-${itemId}`);
  const oldQty = parseInt($el.val(), 10);
  const maxQty = parseInt($el.data('quantityMax'), 10);
  const minQty = parseInt($el.data('quantityMin'), 10);
  const minError = $el.data('quantityMinError');
  const maxError = $el.data('quantityMaxError');
  const newQty = $target.data('action') === 'inc' ? oldQty + 1 : oldQty - 1;
  // Does not quality for min/max quantity
  if (newQty < minQty) {
    return swal({
        text: minError,
        type: 'error',
    });
  } else if (maxQty > 0 && newQty > maxQty) {
    return swal({
        text: maxError,
        type: 'error',
    });
  }
 
  this.$overlay.show();
 
  utils.api.cart.itemUpdate(itemId, newQty, (err, response) => {
    this.$overlay.hide();
 
    if (response.data.status === 'succeed') {
      // if the quantity is changed "1" from "0", we have to remove the row.
      const remove = (newQty === 0);
 
      this.refreshContent(remove);
    } else {
      $el.val(oldQty);
      swal({
          text: response.data.errors.join('\n'),
          type: 'error',
      });
    }
  });
}

Usage in Cornerstone

Item remove

itemRemove (opens in a new tab)

The itemRemove method allows your code to remove items from the cart. This method takes the form utils.api.cart.itemRemove(itemId, callback);.

ParameterTypeDescription/Usage
itemIdstringThe item’s ID.
callbackfunctionAsynchronous function the subject method calls to handle any results.

In the following example (from cart.js), itemRemove is called before the if/else test.

Example: itemRemove
cartRemoveItem(itemId) {
  this.$overlay.show();
  utils.api.cart.itemRemove(itemId, (err, response) => {
    if (response.data.status === 'succeed') {
      this.refreshContent(true);
    } else {
      alert(response.data.errors.join('\n'));
    }
  });
} 

Usage in Cornerstone

Update

update (opens in a new tab)

The update method allows your code to update the set of items in the cart. It takes the form utils.api.cart.update(itemId, qty, callback);.

ParameterTypeDescription/Usage
itemsarrayThe items in the cart.
callbackfunctionAsynchronous function the subject method calls to handle any results.

The following example shows a call to update within the itemUpdate method:

Example: update
itemUpdate(itemId, qty, callback) {
  let callbackArg = callback;
  let items;
 
  if (Array.isArray(itemId) && typeof qty === 'function') {
    callbackArg = qty;
    items = itemId;
  } else {
    items = [
        {
            id: itemId,
            quantity: qty,
        },
    ];
  }
 
  this.update(items, (err, response) => {
    const emitData = {
        items,
        err,
        response,
    };
 
    Hooks.emit('cart-item-update-remote', emitData);
    callbackArg(err, response);
  });
} 

Get item gift wrapping options

getItemGiftWrappingOptions (opens in a new tab)

The getItemGiftWrappingOptions method allows your code to retrieve gift-wrapping options for the current cart item, in customized ways. It takes the form utils.api.cart.getItemGiftWrappingOptions(itemId, callback);.

ParameterTypeDescription/Usage
itemIdstringThe cart item.
callbackfunctionAsynchronous function the subject method calls to handle any results.

The following example (from cart.js) calls getItemGiftWrappingOptions to display gift-wrapping options in a modal.

Example: getItemGiftWrappingOptions
bindGiftWrappingEvents() {
  const modal = defaultModal();
 
  $('[data-item-giftwrap]').on('click', event => {
    const itemId = $(event.currentTarget).data('itemGiftwrap');
    const options = {
      template: 'cart/modals/gift-wrapping-form',
    };
 
    event.preventDefault();
    modal.open();
 
    utils.api.cart.getItemGiftWrappingOptions(itemId, options, (err, response) => {
      modal.updateContent(response.content);
      this.bindGiftWrappingForm();
    });
  });
}

Usage in Cornerstone

Submit item gift wrapping option

submitItemGiftWrappingOption (opens in a new tab)

The submitItemGiftWrappingOption method allows your code to handle the customer’s gift-wrapping selection for the current cart item. This method takes the form utils.api.cart.submitItemGiftWrappingOption(itemId, qty, callback);.

ParameterTypeDescription/Usage
itemIdstringThe cart item.
callbackfunctionAsynchronous function the subject method calls to handle any results.
Example: submitItemGiftWrappingOption
/**
 * Submit giftwrapping options
 *
 * @param {String} itemId
 * @param {Function} callback
 */
submitItemGiftWrappingOption(itemId, params, callback) {
  this.remoteRequest(`/gift-wrapping/${itemId}`, 'POST', { params }, callback);
}

Get content

getContent (opens in a new tab)

The getContent method allows your code to display the cart contents in customized ways. It takes the form utils.api.cart.getContent(options, callback);.

ParameterTypeDescription/Usage
optionsobjectTemplate containing content and totals children.
callbackfunctionAsynchronous function the subject method calls to handle any results.

This example (from cart.js) shows a call to getContent within the refreshContent function.

Example: getContent
refreshContent(remove) {
  const $cartItemsRows = $('[data-item-row]', this.$cartContent);
  const $cartPageTitle = $('[data-cart-page-title]');
  const options = {
    template: {
        content: 'cart/content',
        totals: 'cart/totals',
        pageTitle: 'cart/page-title',
        statusMessages: 'cart/status-messages',
    },
  };
 
  this.$overlay.show();
 
  // Remove last item from cart? Reload
  if (remove && $cartItemsRows.length === 1) {
    return window.location.reload();
  }
 
  utils.api.cart.getContent(options, (err, response) => {
    this.$cartContent.html(response.content);
    this.$cartTotals.html(response.totals);
    this.$cartMessages.html(response.statusMessages);
 
    $cartPageTitle.replaceWith(response.pageTitle);
    this.bindEvents();
    this.$overlay.hide();
 
    const quantity = $('[data-cart-quantity]', this.$cartContent).data('cart-quantity') || 0;
 
    $('body').trigger('cart-quantity-update', quantity);
  });
} 

Usage in Cornerstone

Get shipping quotes

getShippingQuotes (opens in a new tab)

The getShippingQuotes method allows your code to retrieve shipping-cost quotes for the cart’s contents. It returns shippingQuote objects that contain IDs. You must follow getShippingQuotes by calling submitShippingQuote on a quoteId. This method takes the form utils.api.cart.getShippingQuotes(params, renderWith, callback);.

ParameterTypeDescription/Usage
paramsobjectContains country_id, state_id, and zip_code.
templatestring, array, objectThe template to use for rendering.
callbackfunctionAsynchronous function the subject method calls to handle any results.

See submitShippingQuotes for an example.

Usage in Cornerstone

Submit shipping quote

submitShippingQuote (opens in a new tab)

This method takes the form utils.api.cart.submitShippingQuote(quoteId, callback);.

The submitShippingQuote method must be called after getShippingQuote, which returns shippingQuote objects that contain IDs. The cart page renders the shipping quotes. When the user selects one of the quotes, this method sends that quoteId to the backend.

ParameterTypeDescription/Usage
quoteIdnumberID for a shipping quote returned by getShippingQuotes.
callbackfunctionAsynchronous function the subject method calls to handle any results.

The following example from cart/shipping-estimator.js shows calls to both getShippingQuotes and submitShippingQuote.

Example: getShippingQuotes and submitShippingQuote
bindEstimatorEvents() {
  const $estimatorContainer = $('.shipping-estimator');
  const $estimatorForm = $('.estimator-form');
 
  $estimatorForm.on('submit', (event) => {
    const params = {
      country_id: $('[name="shipping-country"]', $estimatorForm).val(),
      state_id: $('[name="shipping-state"]', $estimatorForm).val(),
      city: $('[name="shipping-city"]', $estimatorForm).val(),
      zip_code: $('[name="shipping-zip"]', $estimatorForm).val(),
    };
 
    event.preventDefault();
 
    utils.api.cart.getShippingQuotes(params, 'cart/shipping-quotes', (err, response) => {
      $('.shipping-quotes').html(response.content);
 
      // bind the select button
      $('.select-shipping-quote').on('click', (clickEvent) => {
        const quoteId = $('.shipping-quote:checked').val();
 
        clickEvent.preventDefault();
 
        utils.api.cart.submitShippingQuote(quoteId, () => {
          location.reload();
        });
      });
    });
  }); 
}

Usage in Cornerstone

Apply code

applyCode (opens in a new tab)

The applyCode method applies a coupon code or gift certificate to the cart. It takes the form utils.api.cart.applyCode(code, callback);.

ParameterTypeDescription/Usage
codestringAlphanumeric representation of the coupon or gift-certificate code.
callbackfunctionAsynchronous function the subject method calls to handle any results.

In the following example from cart.js, applyCode is called before the final if/else test to apply a coupon code:

Example: applyCode
bindPromoCodeEvents() {
  const $couponContainer = $('.coupon-code');
  const $couponForm = $('.coupon-form');
  const $codeInput = $('[name="couponcode"]', $couponForm);
 
  $('.coupon-code-add').on('click', (event) => {
    event.preventDefault();
 
    $(event.currentTarget).hide();
    $couponContainer.show();
    $('.coupon-code-cancel').show();
    $codeInput.focus();
  });
 
  $('.coupon-code-cancel').on('click', (event) => {
    event.preventDefault();
 
    $couponContainer.hide();
    $('.coupon-code-cancel').hide();
    $('.coupon-code-add').show();
  });
 
  $couponForm.on('submit', (event) => {
    const code = $codeInput.val();
 
    event.preventDefault();
 
    // Empty code
    if (!code) {
      return alert($codeInput.data('error'));
    }
 
    utils.api.cart.applyCode(code, (err, response) => {
      if (response.data.status === 'success') {
        this.refreshContent();
      } else {
        alert(response.data.errors.join('\n'));
      }
    });
  });
}

Usage in Cornerstone

Apply gift certificate

applyGiftCertificate (opens in a new tab)

This method applies a gift certificate to a cart. It takes the form utils.api.cart.applyGiftCertificate(code, callback);.

ParameterTypeDescription
codestringGift certificate code to apply.
callbackfunctionAsynchronous function the subject method calls to handle any results.

The following example calls appleGiftCertificate.

Example: applyGiftCertificate
utils.api.cart.applyGiftCertificate(code, (err, resp) => {
  if (resp.data.status === 'success') {
    this.refreshContent();
  } else {
    alert({
      text: resp.data.errors.join('\n'),
      type: 'error',
    });
  }
});

Usage in Cornerstone

Countries Resource

These methods allow your theme or app to retrieve standardized country names, by numeric ID or by string.

Country get by id

getById (opens in a new tab)

The country getById method retrieves standardized country names by numeric ID. This method takes the form utils.api.countries.getById(countryId, callback);.

ParameterTypeDescription/Usage
countryIdnumberCountry code.
callbackfunctionAsynchronous function the subject method calls to handle any results.

The following example makes a call to country getById.

Example: getById and getByName
utils.api.countries.getById(countryId, (err, res) => {
  const url = this.endpoint + countryId;
  this.remoteRequest(url, 'GET', {}, callback);
});

Get by name

getByName (opens in a new tab)

The getByName method retrieves states by country name, and returns an array of states that can be used in the callback. It takes the form utils.api.countries.getByName(countryName, callback);.

ParameterTypeDescription/Usage
countryNamestringCountry name
callbackfunctionAsynchronous function the subject method calls to handle any results.

In the following example from common/state-country.js, getByName is called after the initial if test:

Example: getByName
callback(err, element) => {
  if(err) {
    console.log(err);
    return;
  }
  if(element) {
    console.log(element);
    //do something
  }
}
 
$('select[data-field-type="Country"]').on('change', (event) => {
  const countryName = $(event.currentTarget).val();
  if (countryName === '') {
    return;
  }
  utils.api.country.getByName(countryName, (err, response) => {
    if (err) {
      alert(context.state_error);
      return callback(err);
    }
    const $currentInput = $('[data-field-type="State"]');
    if (!_.isEmpty(response.data.states)) {
      // The element may have been replaced with a select, reselect it
      const $selectElement = makeStateRequired($currentInput, context);
      addOptions(response.data, $selectElement, options);
      callback(null, $selectElement);
    } else {
      const newElement = makeStateOptional($currentInput, context);
      callback(null, newElement);
    }
  });
}); 

Usage in Cornerstone

Product Attributes Resource

Option change

optionChange (opens in a new tab)

The optionChange method is fired when the customer selects a product option for the current cart item (for example, changing a shirt’s color from a default "yellow" to "green"). This method takes the form utils.api.productAttributes.optionChange(productId, params, callback);.

ParameterTypeDescription/Usage
paramsobjectContains a collection of IDs that map to product properties (color, size, etc.)
productIdnumberID for this product.
callbackfunctionAsynchronous function the subject method calls to handle any results.

In this example (from common/product-details.js), optionChange is called to update options in a Quick View modal.

Example: optionChange
// Update product attributes. If we're in quick view and the product has options, then also update the initial view in case items are oos
if (_.isEmpty(productAttributesData) && hasOptions) {
  const $productId = $('[name="product_id"]', $form).val();
 
  utils.api.productAttributes.optionChange($productId, $form.serialize(), (err, response) => {
    const attributesData = response.data || {};
 
    this.updateProductAttributes(attributesData);
    this.updateView(attributesData);
  });
} else {
  this.updateProductAttributes(productAttributesData);
} 

Usage in Cornerstone

Configure in cart

configureInCart (opens in a new tab)

This method configures product options in the cart. It takes the form utils.api.productAttributes.configureInCart(itemId, options, callback);.

ParameterTypeDescription
itemIdnumberproduct ID
paramsobject
callbackfunctionAsynchronous function the subject method calls to handle any results.
Example: configureCart
utils.api.productAttributes.configureInCart(itemId, options, (err, response) => {
  modal.updateContent(response.content);
  this.bindGiftWrappingForm();
});

Usage in Cornerstone

Product Resource

Product get by id

getById (opens in a new tab)

The product getById method allows your code to retrieve, and to present, detailed product information by product ID. This method takes the form utils.api.product.getById(productId, params, callback);.

ParameterTypeDescription/Usage
productIdnumberID for this product
paramsobjectContains request options and/or presentation template.
callbackfunctionAsynchronous function the subject method calls to handle any results.
Example: Product getById
$('body').on('click', '.quickview', (event) => {
    event.preventDefault();
    const productId = $(event.currentTarget).data('product-id');
    modal.open({ size: 'large' });
 
    utils.api.product.getById(productId, { template: 'products/quick-view' }, (err, response) => {
      modal.updateContent(response);
 
      modal.$content.find('.productView').addClass('productView--quickView');
 
      return new ProductDetails(modal.$content.find('.quickView'), context);
    });
  }); 

Usage in Cornerstone

Search Resource

The search method allows you to present a customized user interface for search results.

Search

search (opens in a new tab)

The core search method takes the form utils.api.search.search(query, params, callback);.

ParameterTypeDescription/Usage
querystringContains the customer’s search query
paramsobjectContains request options and/or presentation template.
callbackfunctionAsynchronous function the subject method calls to handle any results.
Example: search
const doSearch = _.debounce((searchQuery) => {
  utils.api.search.search(searchQuery, { template: 'search/quick-results' }, (err, response) => {
    if (err) {
      return false;
    }
 
    $quickSearchResults.html(response);
  });
}, 200);

Usage in Cornerstone

Config Object

A config object can be passed in as part of the Stencil Utils API.

The object only returns data in the context of that call. The config will not be available to anything else. It will not surface objects that are not normally available to the page. Use YAML to return objects in the context of an entire page. Some config objects can only be used on the listed pages, while others are available globally.

Example: config
getCartContent(cartItemHash, onComplete) {
  const options = {
    template: 'cart/preview',
    params: {
        suggest: cartItemHash,
    },
    config: {
        cart: {
            suggestions: {
                limit: 4,
            },
        },
    },
  };
  console.log(options);
  return onComplete(options);
}

Product search attributes

Product Search Results (opens in a new tab)

Example: Product search results
{
  "search": {
    "product_results": {
        "limit": 5
    }
  }
}

Brands

Brand list

Brand List Page (opens in a new tab)

Example: Brand list object
{
  "brands": {
    "limit": 5
  }
}

Brand page

Brand Page (opens in a new tab)

Example: Brand page object
{
  "brand": {
    "products": {
      "limit": 5
    }
  }
}

Cart

Cart Page (opens in a new tab)

Example: Cart object
{
  "cart": {
    "suggestions": {
      "limit": 5
    }
  }
}

Product

Product Page (opens in a new tab)

Example: Product object
{
  "product": {
    "videos": {
      "limit": 11
    },
    "images": {
      "limit": 12
    },
    "reviews": {
      "limit": 13
    },
    "related_products": {
      "limit": 14
    },
    "similar_by_views": {
      "limit": 15
    }
  }
}

Blog

Blog Page (opens in a new tab)

Example: Blog object
{
  "blog": {
    "posts": {
      "limit": 5,
      "pages": 3,
      "summary": 10
    }
  }
}

Category

Category Page (opens in a new tab)

Example: Category page object
{
  "category": {
    "shop_by_price": false,
    "products": {
      "limit": 5
    }
  }
}

Global Objects

Products
{
  "products": {
    "featured": 3,
    "new": 4,
    "top_sellers": 10
  }
}

 

Example:
{
  "products": {
    "featured": {
      "limit": "5"
    },
    "new": {
      "limit": "10"
    },
    "top_sellers": {
      "limit": "15"
    }
  }
}

 

All objects
{
  "customer": {
    "addresses": false,
    "returns": true,
    "wishlists": {
      "limit": 3
    },
    "orders": {
      "limit": 4
    },
    "recently_viewed_products": true
  },
  "products": {
    "featured": {
      "limit": 3
    },
    "new": {
      "limit": 4
    },
    "top_sellers": {
      "limit": 5
    }
  },
  "carousel": true,
  "blog": {
    "recent_posts": {
      "limit": 7
    },
    "summary": 6
  },
  "cart": true,
  "shipping_messages": true,
  "categories": {
    "description": true
  },
  "shop_by_brand": {
    "limit": 4
  }
}

Resources

Did you find what you were looking for?