Skip to main content

Using topi Elements

By the time you're done reading this page, you should have a topi Checkout Button rendered on your page.

Let's get started!

Rendering your first element

1. Load the library

In the head of your HTML page, ensure you have the topi Elements library loaded:

<head>
<script
src="https://elements.topi.eu/topi_elements.umd.js"
type="text/javascript"
></script>
</head>
Sandbox

If you are testing topi Elements in Sandbox mode, use the sandbox domain instead: src="https://elements.topi-sandbox.eu/topi_elements.umd.js"

2. Initialize the library

Once the library is fetched, a global object TopiElements will be added to the window object. It’s time to initialize the library with your config:

const topi = new TopiElements({
locale: "de",
widgetId: "your_topi_elements_id",
});

Required parameters:

ParameterPossible valuesDescription
locale (string)en, de, nlLocalization of strings rendered in elements
widgetId (string)(Obtain from your topi point of contact)Unique string scoping the instance to the seller
Share the instance!

If you are using a frontend framework like React, you'll want to share this topi instance throughout your application using, for example, a hook like useContext. How you do that is up to you, but ensuring that you have access to the instance is important for invoking setter functions later on to pass data — e.g. cart items — into the elements.

3. Decide on a placement

Now that the library is initialized, you're ready to add elements to the page.

Let's say you want to render a topi Checkout Button on your Cart page. To do that, drop the HTML custom element in the right place in your HTML (or component tree, if you're using a frontend framework):

<body>
<!-- other elements... -->
<h3>Total: €899.00</h3>

<x-topi-checkout-button></x-topi-checkout-button>
</body>
info

Important: Custom elements like <x-topi-checkout-button> must not use self-closing tag shorthand (e.g. <x-topi-checkout-button />) because HTML parsers treat them differently. This can lead to subtle bugs where the element doesn’t mount or respond as expected. Always use an explicit closing tag: <x-topi-checkout-button></x-topi-checkout-button>.

This wouldn't do anything yet because, by default, a topi Checkout Button would not render if it detects that there are no items in the cart.

So, the final step to see the topi Checkout Button render is to pass in some cart items.

4. Pass in cart contents

The TopiElements instance that you initialized earlier comes with a setter called cartItems. Every time the shopper's cart changes, set the contents:

// the single instance from earlier
// remember to reuse the same instance!
const topi = new TopiElements(config);

topi.cartItems = [
{
price: {
currency: "EUR",
gross: 119000,
net: 100000,
taxRate: 1900,
},
quantity: 1,
sellerProductReference: {
reference: "179321ce-0a89-4b43-a810-7af09a61061d",
source: "SKU",
},
},
];

What happens now?

Under the hood, this triggers an API request to topi directly from the client with the cart information. When the response is received in the client, all the topi elements on the page (in our example so far that's the single Checkout Button) will receive this data and re-render if necessary.

info

If you're wondering if there's an API reference for this, yes! topi Elements uses the same code path internally as the /catalog/carts/rental-overview endpoint. Some of the properties like price is optional, so we recommend taking a look at the reference.

So, if the items that you've passed match with products in your topi catalog, the topi Checkout Button should now render on the page!

screenshot of topi Checkout Button rendered on the cart page in German

Great, you did it! We now have a custom element rendering on your store, which will conditionally render according to the cart contents.

Feel free to open up your browser's Dev Tools and look at the Network tab. You'll see that a request was made to topi with the data you passed in, and topi's server responded with pricing information that is now available throughout your ecom store in the front end.

As briefly mentioned earlier, this response is shared across all topi elements that you've dropped into your pages, which means you don't have to call this every time you add new elements to the page.

Just make sure you keep updating topi Elements with the cart contents using topi.cartItems = [...] and things should just work. If you don't, then be aware that the elements may display incorrect topi pricing information.

Speaking of data and states, let's dive deeper as there is a little bit of complexity that warrants some explanation.

Understanding state in topi Elements

In rendering your first element you would have noticed the coupling between the Checkout Button custom element and the inputs passed into the topi.cartItems = [...] setter. The Checkout Button relies on your cartItems input to determine its behaviour.

But what about other elements and situations? What if, for example, you wanted to render the Checkout Button on the PDP, and you wanted this button to behave according to a single PDP item instead of the whole cart?

This is where an understanding of state management inside of topi Elements becomes helpful.

PDP vs Cart states

We have deliberately designed our state to be separated around distinct segments of the ecom flow:

  • PDP has its own state, and you set it using topi.pdpItem = item
  • Cart has its own state, and you set it using topi.cartItems = [item, item]
  • (coming soon) PLP has its own state, and you set it using topi.plpItems = [item, item]

This separation makes crystal-clear the relationships between the custom elements and the state inside of topi Elements.

So, for example, returning to the Checkout Button on the PDP page, you'd need to do 2 things to make it work. First, tell topi Elements about the current PDP item being viewed:

JavaScript
topi.pdpItem = {
// ...
};

This effectively sets the PDP state in topi Elements, and all elements that need to rely on the PDP state will receive the updated state and render (or re-render) if necessary.

Always call the setter on PDP visits

To ensure that topi is displaying the correct rental price for the item being viewed, always call the setter on page render. If the shopper is revisiting the same item, topi Elements is optimised to not re-render the element.

Since a Checkout Button relies on the Cart state, the second step is to explicitly mark an instance of the element to rely on the PDP state instead. In HTML:

HTML
<x-topi-checkout-button checkout-mode="product"></x-topi-checkout-button>

To summarize:

  • States are managed separately for PDP, Cart, and PLP
  • Elements can be told to use one or the other state, if applicable
  • This separation is designed to make it easy to reason about the behaviours of elements vis-a-vis state

Alright, now that we understand how to render an element and how to think about the state they rely on, we are ready to expand our use of topi Elements to the full suite of what's available.

Choose your next step:

  1. Learn about every single element available
  2. Learn about typical placements of elements by pages