Philosophy
Since the release of Shopify 2.0, we have adopted the use of Custom Elements, first seen in the Dawn theme.
Custom elements provide a native way to contextually bind events and functions to the DOM, without the need for heavy front-end frameworks.
To further aid the effectiveness of Custom Elements, BAO have created a bespoke Custom Element (BAOCustomElement) which includes a number of helper functions, mimicking the old JS Modules helper functions.
Why a base class?
A vanilla Custom Element gives you lifecycle callbacks and not much else. In practice, every component we build needs the same handful of things:
- A predictable way to find its child elements in the DOM.
- A safe place to bind and clean up event listeners.
- Validation so a component fails loudly (in development) when it's missing markup it depends on.
- A consistent hook into Shopify's Section Rendering API for components that re-render on cart/state changes.
- Scoped debug logging that stays quiet in production.
Rather than reimplement these on every element, BAOCustomElement provides them as a shared base class. It is a factory function that returns a class, so you can extend either the default HTMLElement or a more specific built-in.
// Extend the default HTMLElement
class MyElement extends window.BAO.CustomElement() {
setupListeners () {
this.listeners.add(this.els.button.element, 'click', this.handleClick)
}
}
// Customised built-in (e.g. extending <button>)
class MyButton extends window.BAO.CustomElement({ SuperClass: HTMLButtonElement }) {
// ...
}