> 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.

# Customizing JavaScript

Plan: Stencil Developer

Lesson 14 of 31 · 30 min

## Cornerstone Theme Pages

Most Cornerstone theme page template files located in *templates/pages/* have a corresponding *.js file* in *assets/js/theme/*. These JavaScript files contain **event handlers** and **logic** for managing page-specific elements and actions.

For example, *assets/js/theme/product.js* corresponds to *templates/pages/product.html* and contains a *productReviewHandler()* and *bulkPricingHandler()*. These functions are implemented within a derived *Product* class which extends the *PageManager* class. This same pattern is **repeated** in all *assets/js/theme/\*.js* files.

By **default**, all derived *PageManager* classes contain an *onReady* method functionally similar to *JQuery.ready()*. Additionally, certain pages have unique event handlers. For example, the *setApplePaySupport* function in *assets/js/cart.js* is executed and variables like *this.\$cartContent* are populated when the DOM is ready.

Developers can customize and enhance page behavior and functionality by editing code within these event handlers or by creating their own event handlers.

## Modifying a page's JavaScript

In this example, we will add some "**Hello World!**" text to the product page's *onReady* event. We'll first add a call to the function. Then, we will implement the function itself.

First, implement the *helloWorld()* function by adding it to the **Product class** just after the closing *onReady()* bracket.

```js showLineNumbers={false}
export default class Product extends PageManager {
    constructor(context) {
        super(context);
        this.url = window.location.href;
        this.$reviewLink = $('[data-reveal-id="modal-review-form"]');
        this.$bulkPricingLink = $('[data-reveal-id="modal-bulk-pricing"]');
    }

    onReady() {
      // ...

      // Example Code
      this.helloWorld();
    }

    // Example Code
    helloWorld() {
        console.log("[assets/js/theme/product.js]: Hello World!");
    }
    // ...
}
```

Next, in *assets/js/theme/product.js* file, add a call to `this.helloWorld()` to the bottom of the *onReady()* method, which we'll implement in the step below.

```js showLineNumbers={false}
export default class Product extends PageManager {
    constructor(context) {
        super(context);
        this.url = window.location.href;
        this.$reviewLink = $('[data-reveal-id="modal-review-form"]');
        this.$bulkPricingLink = $('[data-reveal-id="modal-bulk-pricing"]');
    }

    onReady() {
      // ...
      // Example Code
      this.helloWorld();
    }
    // ...
}
```

In your browser, refresh any product details pop-up or page to see your new "**Hello World**" message.

## Handlebars Context

### Bringing in Handlebars context

You can inject any variables from the Handlebars context into your client-side JavaScript by using the *\{\{inject...}}* expression.

```text showLineNumbers={false}
{{inject 'productThumbSize' theme_settings.productthumb_size}}
```

To inject *theme* settings.productthumb\_size\_into the product page's context, add `{{inject 'productThumbSize' theme_settings.productthumb_size}}` just under `{{#partial "page"}}` in *templates/pages/product.html*:

```text showLineNumbers={false}
product:
    videos:
        limit: {{theme_settings.productpage_videos_count}}
    reviews:
        limit: {{theme_settings.productpage_reviews_count}}
    related_products:
        limit: {{theme_settings.productpage_related_products_count}}
    similar_by_views:
        limit: {{theme_settings.productpage_similar_by_views_count}}

{{#partial "page"}}
    <!-- Context Injection Example: -->
    {{inject 'productThumbSize' theme_settings.productthumb_size}}
    <!-- End Context Injection Example -->
    <!-- ... -->
{{/partial}}
{{> layout/base}}
```

The injected productThumbSize property can then be accessed from *product.js* by calling *this.context.productThumbSize*.

```js showLineNumbers={false}
export default class Product extends PageManager {
    constructor(context) {
        super(context);
        this.url = window.location.href;
        this.$reviewLink = $('[data-reveal-id="modal-review-form"]');
        this.$bulkPricingLink = $('[data-reveal-id="modal-bulk-pricing"]');
    }

    onReady() {
      //...
        // Example Code
        this.helloWorld();
    }

    // Example Code
    helloWorld() {
      console.log("[assets/js/theme/product.js]: Hello World!");
      console.log("[assets/js/theme/product.js]: " + this.context.productThumbSize);
    }
    // ...
}
```

> **Info**
>
> Note: That the console.log(this.context.themeImageSizes); statement will report the configured image size, following the "Hello World!" message previously defined in the Customizing JavaScript for Individual Pages above.

```text showLineNumbers={false}
[/assets/js/theme/product.js]: Hello World!
product.js:63 [/assets/js/theme/product.js]: 100x100
```

## Installing Libraries

Once you have installed the default Stencil theme, you can add custom JavaScript libraries with npm. The code examples below show how to install the *moment.js* library:

```bash showLineNumbers={false}
npm install moment
```

Next you can import modules from the library into the theme's JavaScript files. For instance, you can add the following import statement to *assets/js/theme/product.js* to load moment on the product page:

```js showLineNumbers={false}
import moment from 'moment'
```

After importing the module, you can access it later in the file. Add the following to the onReady method in *assets/js/theme/product.js* to display an alert with the current time when the page is ready.

```text showLineNumbers={false}
window.alert('Hello world, it is now ' + moment().format('LTS'))
```

The resulting alert will look like:

![Alert with current time](/_fern-img/e16bc442d1a72a6b6d843c84d3a18f65bfbbc08b5b3d4f959f81944e896e6efa.webp)