> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Stencil Utils Reference

[Stencil Utils](https://github.com/bigcommerce/stencil-utils) 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](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/index.js)

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

| Parameter | Type     | Description/Usage                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| :-------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| url       | string   | request URL. For example, `/cart.php`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| options   | object   | Can contain `template`, [FormData (for POST methods)](https://developer.mozilla.org/en-US/docs/Web/API/FormData), `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. |
| callback  | function | Asynchronous 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](/developer/docs/storefront/stencil/utils/queries).

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

**`Example: getPage`**

```js title="Example: getPage" showLineNumbers={false}
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:

* [assets/js/theme/wishlist.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/wishlist.js)
* [assets/js/theme/gift-certificate.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/gift-certificate.js)
* [assets/js/theme/faceted-search.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/common/faceted-search.js)

### Get page by GraphQL

[getPageByGQL](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/index.js)

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](/developer/docs/storefront/stencil/themes/context/frontmatter-reference#graphql-attributes).

| Parameter | Type     | Description/Usage                                                                                                                                                                                                                               |
| :-------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| page      | string   | Presentation 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. |
| callback  | function | Asynchronous function the subject method calls to handle any results.                                                                                                                                                                           |

**`Example: getPageByGQL`**

```js title="Example: getPageByGQL" showLineNumbers={false}
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](https://github.com/bigcommerce/stencil-utils/blob/9cf7c26b0a1f9ca9da83274ebc375e73f20acac5/src/api/cart.js) contents in customized ways.

### Get cart

[getCart](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L11)

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

| Parameter | Type     | Description                                                           |
| :-------- | :------- | :-------------------------------------------------------------------- |
| options   | object   | Return product variant options.                                       |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

**`Example: getCart`**

```js title="Example: getCart" showLineNumbers={false}
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](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L28)

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

| Parameter | Type     | Description                                                           |
| :-------- | :------- | :-------------------------------------------------------------------- |
| options   | object   | Return product variant options.                                       |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

**`Example: getCartQuantity`**

```js title="Example: getCartQuantity" showLineNumbers={false}
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

* [assets/js/theme/global/cart-preview.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/global/cart-preview.js)

### Item add

[itemAdd](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L51)

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

| Argument | Type                                                                         | Description/Usage                                                                                                                                       |
| -------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| FormData | [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) object | Contains all details about the added item and its product options.  FormData example: `action: add` `product_id: 123`  `attribute[123]: 321` `qty[]: 1` |
| callback | Function                                                                     | Asynchronous 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`**

```js title="Example: itemAdd" showLineNumbers={false}
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

* [assets/js/theme/common/product-details.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/common/product-details.js)

### Item update

[itemUpdate](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L70)

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);`.

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| itemId    | string   | The item’s ID                                                         |
| qty       | integer  | The item’s quantity in the cart.                                      |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

**`Example: itemUpdate`**

```js title="Example: itemUpdate" showLineNumbers={false}
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

* [assets/js/theme/cart.js](https://github.com/bigcommerce/cornerstone/blob/d786c6ecbed5ad588ed9489f79e2226455a07b21/assets/js/theme/cart.js)

### Item remove

[itemRemove](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L106)

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

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| itemId    | string   | The item’s ID.                                                        |
| callback  | function | Asynchronous 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`**

```js title="Example: itemRemove" showLineNumbers={false}
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

* [assets/js/theme/cart.js](https://github.com/bigcommerce/cornerstone/blob/d786c6ecbed5ad588ed9489f79e2226455a07b21/assets/js/theme/cart.js)

### Update

[update](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L160)

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);`.

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| items     | array    | The items in the cart.                                                |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

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

**`Example: update`**

```js title="Example: update" showLineNumbers={false}
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](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L132)

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);`.

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| itemId    | string   | The cart item.                                                        |
| callback  | function | Asynchronous 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`**

```js title="Example: getItemGiftWrappingOptions" showLineNumbers={false}
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

* [assets/js/theme/cart.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/cart.js)

### Submit item gift wrapping option

[submitItemGiftWrappingOption](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L150)

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);`.

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| itemId    | string   | The cart item.                                                        |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

**`Example: submitItemGiftWrappingOption`**

```js title="Example: submitItemGiftWrappingOption" showLineNumbers={false}
/**
 * Submit giftwrapping options
 *
 * @param {String} itemId
 * @param {Function} callback
 */
submitItemGiftWrappingOption(itemId, params, callback) {
  this.remoteRequest(`/gift-wrapping/${itemId}`, 'POST', { params }, callback);
}
```

### Get content

[getContent](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L174)

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

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| options   | object   | Template containing content and totals children.                      |
| callback  | function | Asynchronous 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`**

```js title="Example: getContent" showLineNumbers={false}
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

* [assets/js/theme/global/cart-preview.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/global/cart-preview.js)
* [assets/js/theme/cart.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/cart.js)
* [assets/js/theme/common/product-details.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/common/product-details.js)

### Get shipping quotes

[getShippingQuotes](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L193)

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);`.

| Parameter | Type                  | Description/Usage                                                     |
| :-------- | :-------------------- | :-------------------------------------------------------------------- |
| params    | object                | Contains country\_id, state\_id, and zip\_code.                       |
| template  | string, array, object | The template to use for rendering.                                    |
| callback  | function              | Asynchronous function the subject method calls to handle any results. |

See `submitShippingQuotes` for an example.

### Usage in Cornerstone

* [assets/js/theme/cart/shipping-estimator.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/cart/shipping-estimator.js)

### Submit shipping quote

[submitShippingQuote](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L218)

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.

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| quoteId   | number   | ID for a shipping quote returned by `getShippingQuotes`.              |
| callback  | function | Asynchronous 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`**

```js title="Example: getShippingQuotes and submitShippingQuote" showLineNumbers={false}
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

* [assets/js/theme/cart/shipping-estimator.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/cart/shipping-estimator.js)

### Apply code

[applyCode](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L234)

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

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| code      | string   | Alphanumeric representation of the coupon or gift-certificate code.   |
| callback  | function | Asynchronous 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`**

```js title="Example: applyCode" showLineNumbers={false}
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

* [assets/js/theme/cart.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/cart.js)

### Apply gift certificate

[applyGiftCertificate](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/cart.js#L250)

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

| Parameter | Type     | Description                                                           |
| :-------- | :------- | :-------------------------------------------------------------------- |
| code      | string   | Gift certificate code to apply.                                       |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

The following example calls `appleGiftCertificate`.

**`Example: applyGiftCertificate`**

```js title="Example: applyGiftCertificate" showLineNumbers={false}
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

* [assets/js/theme/cart.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/cart.js)

## 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](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/countries.js#L23)

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

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| countryId | number   | Country code.                                                         |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

The following example makes a call to country `getById`.

**`Example: getById and getByName`**

```js title="Example: getById and getByName" showLineNumbers={false}
utils.api.country.getById(countryId, (err, res) => {
  const url = this.endpoint + countryId;
  this.remoteRequest(url, 'GET', {}, callback);
});
```

### Get by name

[getByName](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/countries.js#L34)

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.country.getByName(countryName, callback);`.

| Parameter   | Type     | Description/Usage                                                     |
| :---------- | :------- | :-------------------------------------------------------------------- |
| countryName | string   | Country name                                                          |
| callback    | function | Asynchronous 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`**

```js title="Example: getByName" showLineNumbers={false}
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

* [assets/js/theme/common/state-country.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/common/state-country.js)

## Product Attributes Resource

### Option change

[optionChange](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/product-attributes.js#L24)

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);`.

| Parameter | Type     | Description/Usage                                                               |
| :-------- | :------- | :------------------------------------------------------------------------------ |
| params    | object   | Contains a collection of IDs that map to product properties (color, size, etc.) |
| productId | number   | ID for this product.                                                            |
| callback  | function | Asynchronous 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`**

```js title="Example: optionChange" showLineNumbers={false}
// 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

* [assets/js/theme/common/product-details.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/common/product-details.js)
* [assets/js/theme/cart.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/cart.js)

### Configure in cart

[configureInCart](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/product-attributes.js#L50)

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

| Parameter | Type     | Description                                                           |
| :-------- | :------- | :-------------------------------------------------------------------- |
| itemId    | number   | product ID                                                            |
| params    | object   |                                                                       |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

**`Example: configureCart`**

```js title="Example: configureCart" showLineNumbers={false}
utils.api.productAttributes.configureInCart(itemId, options, (err, response) => {
  modal.updateContent(response.content);
  this.bindGiftWrappingForm();
});
```

### Usage in Cornerstone

* [assets/js/theme/cart.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/cart.js)

## Product Resource

### Product get by id

[getById](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/product.js)

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);`.

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| productId | number   | ID for this product                                                   |
| params    | object   | Contains request options and/or presentation template.                |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

**`Example: Product getById`**

```js title="Example: Product getById" showLineNumbers={false}
$('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

* [assets/js/theme/global/quick-view.js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/global/quick-view.js)

## Search Resource

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

### Search

[search](https://github.com/bigcommerce/stencil-utils/blob/master/src/api/search.js)

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

| Parameter | Type     | Description/Usage                                                     |
| :-------- | :------- | :-------------------------------------------------------------------- |
| query     | string   | Contains the customer’s search query                                  |
| params    | object   | Contains request options and/or presentation template.                |
| callback  | function | Asynchronous function the subject method calls to handle any results. |

**`Example: search`**

```js title="Example: search" showLineNumbers={false}
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

* [assets/js/theme/global/quick-search/js](https://github.com/bigcommerce/cornerstone/blob/master/assets/js/theme/global/quick-search.js)

## 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`**

```js title="Example: config" showLineNumbers={false}
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](https://github.com/bigcommerce/cornerstone/blob/master/templates/pages/search.html)

**`Example: Product search results`**

```json title="Example: Product search results" showLineNumbers={false}
{
  "search": {
    "product_results": {
        "limit": 5
    }
  }
}
```

## Brands

### Brand list

[Brand List Page](https://github.com/bigcommerce/cornerstone/blob/master/templates/pages/brands.html)

**`Example: Brand list object`**

```json title="Example: Brand list object" showLineNumbers={false}
{
  "brands": {
    "limit": 5
  }
}
```

### Brand page

[Brand Page](https://github.com/bigcommerce/cornerstone/blob/master/templates/pages/brand.html)

**`Example: Brand page object`**

```json title="Example: Brand page object" showLineNumbers={false}
{
  "brand": {
    "products": {
      "limit": 5
    }
  }
}
```

### Cart

[Cart Page](https://github.com/bigcommerce/cornerstone/blob/master/templates/pages/cart.html)

**`Example: Cart object`**

```json title="Example: Cart object" showLineNumbers={false}
{
  "cart": {
    "suggestions": {
      "limit": 5
    }
  }
}
```

### Product

[Product Page](https://github.com/bigcommerce/cornerstone/blob/master/templates/pages/product.html)

**`Example: Product object`**

```json title="Example: Product object" showLineNumbers={false}
{
  "product": {
    "videos": {
      "limit": 11
    },
    "images": {
      "limit": 12
    },
    "reviews": {
      "limit": 13
    },
    "related_products": {
      "limit": 14
    },
    "similar_by_views": {
      "limit": 15
    }
  }
}
```

### Blog

[Blog Page](https://github.com/bigcommerce/cornerstone/blob/master/templates/pages/blog.html)

**`Example: Blog object`**

```json title="Example: Blog object" showLineNumbers={false}
{
  "blog": {
    "posts": {
      "limit": 5,
      "pages": 3,
      "summary": 10
    }
  }
}
```

### Category

[Category Page](https://github.com/bigcommerce/cornerstone/blob/master/templates/pages/category.html)

**`Example: Category page object`**

```json title="Example: Category page object" showLineNumbers={false}
{
  "category": {
    "shop_by_price": false,
    "products": {
      "limit": 5
    }
  }
}
```

### Global Objects

**`Products`**

```json title="Products" showLineNumbers={false}
{
  "products": {
    "featured": 3,
    "new": 4,
    "top_sellers": 10
  }
}
```



**`Example: `**

```json title="Example: " showLineNumbers={false}
{
  "products": {
    "featured": {
      "limit": "5"
    },
    "new": {
      "limit": "10"
    },
    "top_sellers": {
      "limit": "15"
    }
  }
}
```



**`All objects`**

```json title="All objects" showLineNumbers={false}
{
  "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

* [Stencil Utils (BigCommerce GitHub)](https://github.com/bigcommerce/stencil-utils)