BigCommerce
Storefront
Widgets
Guides
Enriching Templates with GraphQL

Create Widgets Powered by GraphQL

Widgets are configurable and reusable components of content that merchants can display on their storefront. Widgets consist of a combination of HTML/CSS, JavaScript, and Handlebars, and are rendered as part of the storefront’s HTML.

In this tutorial, we will walk you through the process of creating a product widget powered by BigCommerce's Widgets API and GraphQL Storefront API. This setup allows widgets to dynamically update and display information such as product name, image, and price. By the end of this tutorial, you should have a functional widget that is configurable via the Page Builder (opens in a new tab) UI in a store's control panel.

Prerequisites

The steps in this tutorial assume that you are familiar with BigCommerce’s Widgets API, and have obtained the API access_token with the content modify scope. The API access_token is required to inject, remove, and list widgets into any page of the store. To learn more about the Widgets API, see Widgets API Overview. For information on how to create an API account, see Creating an API Account (opens in a new tab).

Create the widget template

To create a widget, you first need to create a template for it. To create a widget template, send a POST request to /v3/content/widget-templates.

Example request: Create a widget template
POST https://api.bigcommerce.com/stores/{{STORE_HASH}}/v3/content/widget-templates
X-Auth-Token: {{ACCESS_TOKEN}}
Content-Type: application/json
Accept: application/json
 
{
  "name": "Product Widget",
  "storefront_api_query": "query Product($productId: Int = 1, $activeCurrencyCode: currencyCode) { site { product(entityId: $productId) { name entityId prices(currencyCode: $activeCurrencyCode) { price { currencyCode value } } defaultImage { url(width: 500, height: 500) } } } } ",
  "schema": [
    {
      "type": "hidden",
      "settings": [
        {
          "type": "graphQl",
          "id": "graphQueries",
          "typeMeta": {
            "mappings": {
              "productId": {
                "reads": "productId",
                "type": "Int!"
              }
            }
          }
        }
      ]
    },
    {
      "type": "tab",
      "label": "Content",
      "sections": [
        {
          "label": "Product",
          "settings": [
            {
              "type": "productId",
              "label": "Product",
              "id": "productId",
              "default": "",
              "typeMeta": {
                "placeholder": "Search by name or SKU"
              }
            }
          ]
        }
      ]
    }
  ],
  "template": "<div style=\"text-align:center\">\n<h1>{{_.data.site.product.name}}</h1>\n<div>\n<img src=\"{{_.data.site.product.defaultImage.url}}\">\n</div>\n<div>\n<p>${{_.data.site.product.prices.price.value}}</p>\n</div>\n</div>"
}
PropertyTypeDescription
namestringThe name of the widget template.
schemaobjectThe widget settings JSON schema for Page Builder (opens in a new tab) UI.
templatestringThe widget template rendered as Handlebars HTML.
storefront_api_querystringGraphQL Storefront API query that provides widget data; accessed in a template via {{_.data}}.

GraphQL queries

The storefront_api_query field allows you to query store data that widgets can use. The widget configuration provides the values for the storefront_api_query parameters. For example, the $productId parameter comes from the widget configuration when a user selects a product. The mappings object from the widget template schema settings tells the widget to map the value of the widget configuration’s productId setting to the GraphQL parameter called productId.

  • You can use the activeCurrencyCode query parameter to return user-selected currency.
  • There is no need to provide the mapping for the activeCurrencyCode property as it is auto-populated with the shopper’s active currency at the time of page load.

Place the widget using Page Builder

After creating the widget template, you should see it listed in Page Builder under Custom.

Custom widgets

Drag and drop the widget onto the desired page, select a product from the product picker, then publish your widget.

Product widget preview

Doing so creates a widget and a widget placement. For more information on placing and configuring widgets in the control panel, see Page Builder (opens in a new tab) in the Help Center.

To view the widget's data, retrieve the widget's ID by accessing its data-widget-id attribute in the browser's developer tools, then pass it in a GET request to /v3/content/widgets/{uuid}.

Alternatively, you can send a GET request to /v3/content/widgets, passing your widget_template_uuid as a query parameter.

The response should be similar to the following example:

 
{
  "data": [
    {
      "channel_id": 1,
      "date_created": "2021-04-09T21:27:21.163Z",
      "date_modified": "2021-04-09T21:40:47.892Z",
      "description": "",
      "name": "Product Widget",
      "storefront_api_query_params": {
        "productId": 77
      },
      "uuid": "7e6d7a11-164e-4eb1-ae0a-af07f3e2c8fb",
      "version_uuid": "3f4defcf-2429-425d-8e5a-7c3807fa9896",
      "widget_configuration": {
        "_": {
          "id": "7e6d7a11-164e-4eb1-ae0a-af07f3e2c8fb"
        },
        "productId": "77"
      },
      "widget_template": {
        "channel_id": 1,
        "client_rerender": false,
        "current_version_uuid": "3f4defcf-2429-425d-8e5a-7c3807fa9896",
        "date_created": "2021-04-09T21:23:16.274Z",
        "date_modified": "2021-04-09T21:23:16.274Z",
        "icon_name": "default",
        "kind": "custom",
        "name": "Product Widget",
        "schema": [
          {
            "settings": [
              {
                "id": "graphQueries",
                "type": "graphQl",
                "typeMeta": {
                  "mappings": {
                    "productId": {
                      "reads": "productId",
                      "type": "Int!"
                    }
                  }
                }
              }
            ],
            "type": "hidden"
          },
          {
            "label": "Content",
            "sections": [
              {
                "label": "Product",
                "settings": [
                  {
                    "default": "",
                    "id": "productId",
                    "label": "Product",
                    "type": "productId",
                    "typeMeta": {
                      "placeholder": "Search by name or SKU"
                    }
                  }
                ]
              }
            ],
            "type": "tab"
          }
        ],
        "storefront_api_query": "query Product($productId: Int = 1, $activeCurrencyCode: currencyCode) { site { product(entityId: $productId) { name entityId prices(currencyCode: $activeCurrencyCode) { price { currencyCode value } } defaultImage { url(width: 500, height: 500) } } } } ",
        "template": "<div style=\"text-align:center\">\n<h1>{{_.data.site.product.name}}</h1>\n<div>\n<img src=\"{{_.data.site.product.defaultImage.url}}\">\n</div>\n<div>\n<p>${{_.data.site.product.prices.price.value}}</p>\n</div>\n</div>",
        "template_engine": "handlebars_v3",
        "uuid": "95eaa664-b19e-4a31-b9c7-498f9bc60bae"
      }
    }
  ],
  "meta": {...}
}

The value of the productId inside of the widget_configuration object is mapped to the productId parameter of the storefront_api_query_params object.

Place the widget using the API

It is also possible to place widgets programmatically using the API. First, create a widget by sending a POST request to /v3/content/widgets.

POST https://api.bigcommerce.com/stores/{{STORE_HASH}}/v3/content/widgets
X-Auth-Token: {{ACCESS_TOKEN}}
Content-Type: application/json
Accept: application/json
 
{
  "name": "Product Widget",
  "widget_template_uuid": "{{TEMPLATE_UUID}}"
}

Take note of the widget's uuid returned in the response. You will need the widget's uuid to create a placement for your widget.

Response:

{
  "data": {
    "uuid": "{{WIDGET_UUID}}",
    ...
  }
}

To create a placement, send a POST request to /v3/content/placements.

POST https://api.bigcommerce.com/stores/{{STORE_HASH}}/v3/content/placements
X-Auth-Token: {{ACCESS_TOKEN}}
Content-Type: application/json
Accept: application/json
 
{
  "widget_uuid": "{{WIDGET_UUID}}",
  "template_file": "{{TEMPLATE_FILE}}",
  "status": "active",
  "region": "{{REGION}}"
}

For a list of accepted template_file values, see create a placement.

To get a list of theme regions for the region property, send a GET request to /v3/content/regions?template_file={{TEMPLATE_FILE}}.

GET https://api.bigcommerce.com/stores/{{STORE_HASH}}/v3/content/regions?template_file={{TEMPLATE_FILE}}
X-Auth-Token: {{ACCESS_TOKEN}}
Accept: application/json

Related resources

Articles

Endpoints

Did you find what you were looking for?