Subscription Manager Development Guide
Nunjucks templating, lit-html expressions, filters, objects, and common pitfalls for SM customization
Ordergroove’s Subscription Manager is built with a custom implementation of Nunjucks to maximize readability and ease of development without compromising performance on your store. This guide is aimed at developers with a good understanding of HTML, CSS, and JavaScript who are looking to customize their Subscription Manager.
Requirements
This guide is relevant for developers working on either v0 or v25 of the Subscription Manager. All examples are taken from v25.
Overview
Ordergroove’s Subscription Manager is built on a custom implementation of Nunjucks which transpiles into a lit-html web component to be sent to the customer. This implementation enables the Subscription Manager to be built with the intuitive feel of a templating language, while maximizing DOM responsiveness to changes by the customer without necessitating a full-page refresh.
During development pre-compilation, the Subscription Manager templates are written as a combination of Nunjucks and lit-html.
Fundamentals
This section walks through the fundamentals of Ordergroove’s Subscription Manager templating language.
Nunjucks Tags and Expressions
The primary means of logic in the Subscription Manager are Nunjucks tags and expressions. Key tags that are implemented are if, set, for, and include. These tags are used in {% %} brackets, just like in Nunjucks, and can be used to add logic around variables and what you want to render.
Example of if and set:
Example of for and include:
The set keyword sets variables to primitives or objects. The include keyword injects another .liquid file into that location — when a file is included, its code is inserted as if it were placed there directly. You always need to include the absolute folder path of the partial from the base views folder in your include path, even if you’re referencing a file from the same subfolder.
Nunjucks variables and expressions can be displayed using {{ }} brackets. For example, <p>{{ badge_class }}</p> would display the value of badge_class in a paragraph.
Objects
The Subscription Manager relies on objects containing customer subscription data. On load, the Subscription Manager retrieves all data for the customer and stores it in the Redux store. Objects from the Redux store can be accessed directly through the Nunjucks template.
Some objects are documented in the Object Reference, but the Redux store itself is an excellent place to check what is available for your customers, since some features may be enabled on your store that aren’t shown in the documentation. See the Debugging with Redux guide for more information.
Filters and Pipes
Nunjucks filters are used with pipes to modify and manipulate objects, variables, and strings. To use a filter, place a pipe and the filter inside Nunjucks brackets. For example, the t filter indicates that the string preceding it should be passed to the locales files to be matched with text content in the current language. {{ 'cancel_subscription_button' | t }} inserts the translation for the cancel_subscription_button key in the locales file.
Filters can be chained left to right, with the output of the left-most filter serving as the input for the next filter.
The | js filter takes in a JavaScript function. It can be passed either the name of a JavaScript function in script.js, or an inline function as a string — for example, '(e) => console.log(e)' | js. The next section discusses lit-html event bindings, the primary usage for this filter.
The | action filter wires up a form to a JavaScript handler that validates the data and submits it to Ordergroove’s APIs. These handler functions are not available to external developers.
The other implemented filters are described in the table below. More details can be found at https://static.ordergroove.com/@ordergroove/smi-core/latest/docs/index.html in the Filters folder.
If you need a filter that is not already implemented, please create a ZenDesk ticket with the filter and desired functionality.
Lit-HTML Expressions
Because Subscription Manager files ultimately compile to lit-html, many of lit-html’s expressions are available in addition to Nunjucks-style templating.
Event Listeners
The Ordergroove Subscription Manager supports adding event listeners to HTML elements with @ expressions through lit-element. Lit’s documentation on this is available here.
For example, @click="{{ 'SMDialog.open' | js }}" means that on the click event, the JavaScript method open from the SMDialog custom element will be called.
Boolean Checks
Boolean attributes in lit-element allow conditional setting of HTML attributes using ? at the beginning of the attribute. Lit’s documentation on this is available here.
Property Setting
Lit-html’s property syntax allows setting a property on an element instead of the attribute. Lit’s documentation on this is available here.
For example, <input .value=${value}> sets the value property directly rather than the attribute (which would only set the default value). This is useful when setting a complex data property like an array or object, or when setting an element’s property differs from setting its attribute.
Comments
Comments in the Subscription Manager are marked within {# #} brackets. Anything within these brackets will not be displayed in the DOM.
Common Mistakes
Property Accesses on Null Objects
Variables in the Subscription Manager have global scope but are not always defined when the Subscription Manager loads. This can lead to inconsistent loading states if a variable is used without checking whether it is defined first. The most common example is accessing a property on an object — like product.name — without first establishing that product is defined and non-null. If you have made customizations to your SM and encounter loading issues, check all property accesses and ensure the object is non-null.
Duplicate IDs
Some Subscription Manager liquid files render inputs with specific IDs. For example, sku-swap-product-change-dialog.liquid includes <label> elements with a for attribute set to the id of the corresponding <input>:
In HTML, IDs are global. If you include this file multiple times on your theme when making customizations, you may end up with multiple <input> elements sharing the same ID. This can cause issues with those inputs — if you’re having trouble selecting a radio input option, check that it’s the only input on the page with that ID.