Checkout extension reference
This page covers the mechanics of a checkout extension: the extend function, the HTML template it renders, and how to hide native checkout modules. The extension points themselves are listed in Extension points, and the data and event APIs in CheckoutAPI reference. For the development workflow, see Create a Checkout Extension. For practical scenarios, see Checkout Extension Recipes.
Extension points
Extension points define where custom content is inserted into the page. Specify the corresponding name in the extensionPoint field of extend(), and the content is rendered at that location.
The checkout page and the thank-you page each offer a fixed set of extension points, grouped by the area of the page they render in. Some of them are dynamic: they render once per line item, per shipping line or per dialog, so the name carries the id of that row and has to be built at runtime.
For the full list, the area each point belongs to, and the native modules you can hide alongside it, see Extension points.
Hiding native modules (deleteTarget)
deleteTarget hides native modules on the checkout page, such as section titles, the address book, or the step breadcrumb.
Declare it in an extension.json file placed in the extension directory, alongside shoplazza.extension.toml:
extensions/
└── my-checkout/
├── shoplazza.extension.toml
├── extension.json # Only deleteTarget is written by you
├── package.json
└── src/
extension.json:
{ "deleteTarget": ["contactInformationHeader", "shippingAddressHeader"] }
To apply the configuration:
- Upgrade the Shoplazza CLI to 2.0.10 or later.
- Restart
shoplazza app devto preview, or runshoplazza app deployto publish.shoplazza app devdoes not watchextension.json, so restart it after every change to the file. - To show the modules again, set
"deleteTarget": []and deploy once more. - The CLI writes
extensionIdandversionback intoextension.json. Keep both fields — do not fill them in by hand and do not delete them.
Available targets
| Target | Location | Description |
|---|---|---|
header | Page header | Store name and logo area at the top |
navigate | Page header | Step breadcrumb, such as Information, Shipping, Payment |
loginOrLogout | Page header | Log in / log out link |
returnBtn | Page header | Return link, rendered next to the submit button |
contactInformation | Contact information | The whole contact information module |
contactInformationHeader | Contact information | The "Contact" title |
contactEmail | Contact information | Email input |
contactPhone | Contact information | Phone number input |
emailOrPhone | Contact information | Combined email or phone input, used when the store accepts either |
contactSubscribe | Contact information | Marketing email subscription checkbox |
shippingAddress | Address | The whole shipping address module |
shippingAddressHeader | Address | The "Shipping address" title |
shippingAddressBook | Address | Address book for picking a saved address |
securityIdentifier | Address | Security and privacy identifier |
addressCard | Address | Filled-in information card, shown on the shipping and payment steps |
billingAddress | Address | Billing address module on the payment step |
deliveryMethod | Delivery and pickup | Delivery method module that switches between shipping and pickup |
deliveryMethodHeader | Delivery and pickup | Delivery method title |
shippingList | Delivery and pickup | Shipping rate list |
shippingLinesTitle | Delivery and pickup | Shipping rate list title |
pickupInformation | Delivery and pickup | Pickup information module |
pickupInformationHeader | Delivery and pickup | Pickup information title |
pickupAddress | Delivery and pickup | Pickup location address list |
pickupAddressHeader | Delivery and pickup | Pickup location address title |
paymentHeader | Payment | Payment method list title |
payPalExpress | Payment | PayPal express checkout button |
infoSubmit | Submit buttons | "Continue to shipping" on the information step |
shippingSubmit | Submit buttons | "Continue to payment" on the shipping step |
paymentSubmit | Submit buttons | "Place order" on the payment step |
orderSummary | Order summary | The whole order summary, in the right column on desktop and at the top on mobile |
orderSummaryHeader | Order summary | Order summary title, collapsible on mobile |
productList | Order summary | Line item list |
ProductListCover | Order summary | Line item thumbnail |
productListSkuProperties | Order summary | Custom line item properties, rendered only when properties is not empty |
priceList | Price breakdown | The whole price breakdown |
priceListSubTotal | Price breakdown | Subtotal |
priceListShippingTotal | Price breakdown | Shipping |
priceListTaxTotal | Price breakdown | Tax |
priceListShippingTaxTotal | Price breakdown | Shipping tax |
priceListGiftCard | Price breakdown | Gift card deduction |
totalPrice | Price breakdown | Total |
reductions | Discounts and notes | Discount code and gift card input area |
mobileCoupon | Discounts and notes | Discount code input on mobile, hidden on desktop |
giftCardTag | Discounts and notes | Applied discount code or gift card tag, with a remove button |
specialInstruction | Discounts and notes | Order note input on the shipping step |
thankyouHeader | Thank-you page | Checkout completion header |
thankyouContent | Thank-you page | Checkout completion content |
thankyouFooter | Thank-you page | Checkout completion footer |
thankyouShippingInfo | Thank-you page | Shipping information block, shown for orders that ship |
thankyouFailOrderStatus | Thank-you page | Failure message shown when the order is cancelled or has failed |
thankyouPageGiftCardAddress | Thank-you page | Billing address and gift card information, shown for virtual-product orders |
thankyouPagePickupAddress | Thank-you page | Pickup address, shown for pickup orders |
CheckoutAPI reference
CheckoutAPI is the global object the checkout platform mounts on window.CheckoutAPI, on the checkout page and on the thank-you page. Through it an extension reads the order and the choices the buyer has made, listens for those values changing, and drives part of the checkout UI.
Its methods are grouped into namespaces: address, base, config, coupon, exception, extension, order, payment, pickup, step, store, summary, track, user and utils.
For every namespace, the type definitions, and the rules that apply before you call anything — when the object is mounted, how to pair on* with remove*, and why register* methods are not listeners — see CheckoutAPI reference.
extend function and HTML template
extend function
extend is the core function for registering content to an extension point. It is imported from shoplazza-extension-ui:
import { extend } from 'shoplazza-extension-ui';
extend({
extensionPoint: 'Checkout::Navigate::RenderBefore',
component: '<h1>Hello, Shoplazza!</h1>',
});
| Parameter | Type | Required | Description |
|---|---|---|---|
extensionPoint | string | Yes | Where the content renders. See Extension points. |
component | string or Promise<string> | Yes | The HTML to render. A plain string works on its own; a Promise<string> requires type: 'spz'. |
type | 'spz' | No | Leave it out for the minimal form. 'spz' turns on the LessJS component library and the placeholder substitution described below. |
localeMap | object | No | Messages for the ${i18n('key')} placeholders in component, keyed by locale. Only used when type is 'spz'. |
id | string | No | The extension id. Pass __EXTENSION_ID__, which the CLI replaces at build time with your extension's name. |
Without type, component is an HTML string rendered as is. That is the minimal form shown above, and it is all most extensions need.
With type: 'spz', the SDK does three extra things before rendering: it loads the LessJS component library, it accepts a Promise<string> as component, and it substitutes the placeholders in your HTML with localeMap:
import { extend } from 'shoplazza-extension-ui';
extend({
type: 'spz',
extensionPoint: 'Checkout::Navigate::RenderBefore',
component: Promise.resolve(
"<div>${i18n('greeting')} - ${i18n('promo.line')}</div>"
),
localeMap: {
'en-US': { greeting: 'Hello', promo: { line: 'Free returns within 30 days' } },
'zh-CN': { greeting: '你好', promo: { line: '30 天内免费退货' } },
},
id: __EXTENSION_ID__,
});
- The key inside
${i18n(...)}must be quoted:${i18n('greeting')}is substituted, while${i18n(greeting)}renders asundefined. - Nested keys are flattened with a dot, so
promo: { line: … }is read as${i18n('promo.line')}. - Which map is used depends on the buyer's full locale, the key of each entry in
localeMap. - Write the HTML as an ordinary quoted string, not a template literal, so that JavaScript leaves the
${…}placeholders for the SDK to substitute. - The placeholder
{EXTENSION_POINT}is substituted with an id derived from the extension point name, for exampleCheckout-Summary-RenderBefore-IDforCheckout::Summary::RenderBefore.
Security Note (XSS Risk): component is a directly rendered HTML string. Do not concatenate unsanitized user input or external API return values into it to avoid XSS injection. For any dynamic content, perform HTML escape first, or use DOM APIs like createElement / textContent instead.
Multiple calls to the same extension point: The same extensionPoint can be extend-ed multiple times. Content will be appended in call order, not overwritten.
HTML template
For complex content, we recommend splitting HTML into separate files. The scaffolding generates the following file structure by default:
src/index.html (optional, assembly entry):
<div>
import './style.html'
import './content.html'
import './script.html'
</div>
import './xxx.html' is not ES Module syntax. It is a text concatenation directive recognized by shoplazza-cli at build time. During the bundling phase, the CLI replaces the import './xxx.html' line with the actual content of ./xxx.html (inlined in order of appearance), rather than loading it dynamically at runtime.
- This syntax can only be used at the top level of
src/index.htmlas an assembly entry. It will not be recognized inside<script>tags or in JS files. - Imported HTML fragments should not contain further
importdirectives to avoid recursion. - For simple content or scenarios requiring dynamic HTML generation, you can skip template files and directly pass concatenated strings to
componentinindex.js.
src/style.html (optional, styles):
<style>
.my-block {
padding: 12px;
background: #f5f5f5;
}
</style>
src/content.html (optional, page content):
<div class="my-block">
<h2>Hello, Shoplazza!</h2>
</div>
src/script.html (optional): Scaffolding placeholder. To write scripts within an HTML template fragment, use a regular <script> tag:
<script>
document.querySelector('.my-block').addEventListener('click', function() {
window.CheckoutAPI.step.goToHomePage();
});
</script>
You can also skip HTML templates entirely and construct HTML strings directly in index.js for component. This suits simple content or dynamic generation.
Checkout page performance directly impacts conversion rate. Keep your extension JS/CSS as lean as possible: aim for < 30KB gzipped per extension, avoid large dependencies, and prefer passive approaches like setTimeout / IntersectionObserver over high-frequency polling.