Add the widget
Load the TeakOS Widget on your checkout page and pass in the cart.
The TeakOS Widget shows the protection offer, prices it for the customer's cart, and records their choice. It takes three things: the loader script, a placeholder element, and a configure call.
1. Add the loader script
Add this to the <head> of every page that shows the widget:
<script>
(function (w, d, c, n, s, p) {
w[n] = w[n] || function () { (w[n].q = w[n].q || []).push(arguments); };
w[n].l = +new Date();
s = d.createElement(c);
p = d.getElementsByTagName(c)[0];
s.async = true;
s.type = 'module';
s.src = 'https://icw.helloteak.com/teak.js';
s.onerror = function () {
// Optional: the widget script couldn't load. Continue checkout without protection.
};
p.parentNode.insertBefore(s, p);
})(window, document, 'script', 'teak');
</script>The loader defines a global teak function straight away and queues your calls until teak.js has loaded. So you can call teak(...) anywhere after the loader. The script loads asynchronously, so it doesn't slow down your page.
2. Add the placeholder element
Put the widget element where the offer should appear, usually just above the order total or the Place order button:
<teak-widget></teak-widget>The widget renders inside this element. It stays empty until you call configure, and is removed if the widget can't load, so your layout shouldn't depend on it.
3. Configure the widget with the cart
Call configure with your public key and the items in the cart:
teak('configure', {
apiKey: 'pk_...', // your public key
sandbox: true, // remove for production
currency: 'USD',
locale: 'en_US',
items: [
{
name: 'Summer Fest - General Admission',
referenceNumber: 'ITEM-1', // your ID for this line item
productTypes: ['general-admission'], // your inventory system's label
cost: 120.0, // price of one item, in `currency`
event: {
name: 'Summer Fest',
location: 'Austin, TX',
startDatetime: '2026-07-18T18:00:00-05:00',
endDatetime: '2026-07-18T23:00:00-05:00',
},
},
],
loadedCb: () => { /* see Handle the customer's choice */ },
optInCb: () => {},
optOutCb: () => {},
onErrorCb: () => {},
});Pass one entry in items for each item the customer is buying. If they buy two tickets, send two entries. Give each item its productTypes: the label your inventory system uses for that product, which Teak maps to protection during onboarding. See Product types.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The item's name, as the customer sees it. |
referenceNumber | string | Yes | Your ID for the item. It comes back in webhooks as reference_number, so you can match contracts to your items. |
productTypes | string[] | Yes, unless a widget element has an id | Product type identifier from your inventory system. Teak maps these values to protection products during onboarding and account setup, so you can send the same product labels you use internally. Work with your Teak integration contact to define these values during onboarding. See Product types. |
cost | number or numeric string | Yes | The price of one item, in currency, including its share of taxes and fees (see below). Protection is priced from it. |
event | object | Yes | The event the item is for. |
event.location | string | Yes | Where the event takes place. |
event.name | string | Recommended | The event's name. |
event.startDatetime | string | Recommended | When the event starts, as an ISO 8601 date-time. |
event.endDatetime | string | Recommended | When the event ends, as an ISO 8601 date-time. |
metadata | object | Extra details Teak uses to choose the right protection for the item, for example a ticket type. Only send it if your Teak integration contact asks you to, using the keys they give you. |
If name, referenceNumber, or event.location is missing, the widget doesn't render, and the browser console says which field is missing: see E4026 and E4027. Without a product type Teak has mapped, Teak can't quote the item.
Taxes and fees. Include taxes and fees in each item's cost, split across items in proportion to their price. For example, two $50.00 tickets with $5.00 tax and a $10.00 fee are each 57.50. This way, an approved refund request returns everything the customer paid for the item. Don't include the protection price itself.
Free items. Leave items that cost $0.00 out of items. They can't be protected, and a cost of 0 stops the widget from rendering.
When the widget loads, it prices protection for the cart, shows the offer, and calls loadedCb.
See Configuration options for every other option.
Showing the widget on more than one page
The widget keeps the same session for 120 minutes across pages on the same domain, so a cart page and a checkout page share one quote. On each page, add the placeholder element and call configure with the current cart.
To carry the customer's choice from one page to the next, add persist: true to configure. Without it, the customer chooses again on each page.
Next steps
The widget is on your checkout page. Next, react to the customer's choice:
- Handle the customer's choice to keep your order total right, keep the widget in step with the cart, and handle errors.
- Check every option and item field in configuration options.
Updated 19 days ago
