Solution Recipe: Internationalisation — The Product Catalog

Olaf
10 min read
For developers
March 27, 2023

Solution Recipes are tutorials to achieve specific objectives in Klaviyo. They can also help you master Klaviyo, learn new third-party technologies, and come up with creative ideas. They are written mainly for developers and technically-advanced users.

Note: We do our best to make sure any code and API references are accurate and current when this is published, but you might need to update code and it’s always a best practice to leverage our latest API versions. If you have questions, feel free to hop over to our Developer Community.

What you’ll learn

In this Solution Recipe, you will learn how to set up Klaviyo to support your international business. This article will help you understand how to structure your product catalog to support your international efforts.

Why it matters

The product catalog is one of the most complex challenging areas to get right due to the complexities of trading in multiple regions. Doing it the right way will make product recommendations simpler across all your markets.

Level of sophistication

Moderate

Code snippet example for localised product catalog

Introduction

Klaviyo offers many ‘out of the box’ integrations with the major eCommerce platforms. These integrations will automatically synchronise the products from the integrations catalog. This is a very powerful feature which allows retailers to quickly get started, and immediately use these products for recommendation blocks. This functionality is perfect for single market, currency and language catalogs.

Klaviyo also supports custom catalogs where the retailer can directly influence what product data points are stored in Klaviyo, and how they are represented to best meet the needs of the business requirements.

Custom catalogs can be added to Klaviyo in two ways:

  1. JSON or XML Feed. This feed is processed and updated every 6 hours.
  2. Catalog API. This allows for real-time updates to product data.

This guide will outline how to best structure the data within a custom catalog to support your businesses international requirements.

The Catalog Challenge

Selling internationally is complex, and every business has their own set of nuances that make data modelling a challenge. When selling in multiple markets, businesses need to consider:

  • Currencies & conversion rates
  • Language translations
  • Logistics, fulfilment & distribution
  • Availability and restrictions

Potential Solutions

There are multiple ways to model data within Klaviyo, and each has its pros and cons. This article aims to highlight the most common models, and provide you with the guidance to help decide which one is right for you.

Note: A reminder, you will need to generate a product feed (XML or JSON) or use the Catalog API that model the formats explained below. This is then imported into Klaviyo

Option 1) — The Localised Product Model

Using the localised product model, each product within Klaviyo is split into localised products.

What does this mean?

Say you sell in 3 markets (US, UK & DE), each market has its own language, price and availability.

A single product can then be split into 3 localised products.

For example, a product with the SKU KLAVIYO-TSHIRT1 would become three individual products, represented by a product_id that matches the market it is available for:

  • KLAVIYO-TSHIRT1_US
  • KLAVIYO-TSHIRT1_UK
  • KLAVIYO-TSHIRT1_DE

As each of these now represent the localised version of that product, the data within can be specific to that market.

The structure of the product catalog you create would look something like this:

[
  {
    "id":"KLAVIYO-TSHIRT1_US",
    "title":"Classic Klaviyo T-Shirt 1",
    "link":"https://klaviyogear_US.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1",
    "description":"Standard issue for all Klaviyos. This t-shirt has the Klaviyo logo on the front and mark diagram on the back.",
    "price":20,
    "currency": "USD",
    "image_link":"https://www.klaviyo.com/media/images/examples/products/klaviyo-tshirt-thumbnail.png",
    "categories":["apparel","t-shirt","new-arrival","swag"],
    "inventory_quantity":190,
    "inventory_policy":1
  },
  {
    "id":"KLAVIYO-TSHIRT1_UK",
    "title":"Classic Klaviyo T-Shirt 1",
    "link":"https://klaviyogear_UK.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1",
    "description":"Standard issue for all Klaviyos. This t-shirt has the Klaviyo logo on the front and mark diagram on the back.",
    "price":15,
    "currency": "GBP",
    "image_link":"https://www.klaviyo.com/media/images/examples/products/klaviyo-tshirt-thumbnail.png",
    "categories":["apparel","t-shirt","new-arrival","swag"],
    "inventory_quantity":70,
    "inventory_policy":1
  },
  {
    "id":"KLAVIYO-TSHIRT1_DE",
    "title":"Klassisches Klaviyo-T-Shirt 1",
    "link":"https://klaviyogear_DE.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1",
    "description":"Standardausgabe für alle Klaviyos. Dieses T-Shirt hat das Klaviyo-Logo auf der Vorderseite und ein Markendiagramm auf der Rückseite.",
    "price":18,
    "currency": "EUR",
    "image_link":"https://www.klaviyo.com/media/images/examples/products/klaviyo-tshirt-thumbnail.png",
    "categories":["apparel","t-shirt","new-arrival","swag"],
    "inventory_quantity":30,
    "inventory_policy":1
  }
]

How to localise a Klaviyo template with this product data

By using the {% catalog lookup tag %}, you can build your product data as follows:

{% catalog "KLAVIYO-TSHIRT1_DE" %}
  {{ catalog_item.title }}
{% endcatalog %}

Pros

  • Can utilise Klaviyo’s default product block functionality
  • Each product has its own inventory and availability
  • As there are now products per market, the reporting and data derived from it, will power localised recommendations.
  • You can break the feeds into individual feeds per market, as each product has a unique ID, they will not be overwritten.

Cons

  • You will need to customise product related events (e.g. Viewed Product, Ordered Product, Placed Order, etc) to use the localised product ID. This is important for reporting, recommendations and catalog lookups.
  • Each localised product will be treated as its own product, therefore the reporting will not be aggregated to the SKU.
  • You cannot dynamically reference a localised product in a flow or a template. A campaign/Flow message for each market will need to be created.

Option 2) — The Localised Attribute Product Model

Using the localised attribute product model, each product within Klaviyo contains all the localisation data that you could need.

How?

Instead of creating multiple products to store the localised data, the data is stored in localised attributes within the single product.

This approach is often favoured by many merchants as it allows the product to be represented by their SKU without the need to create multiple versions.

Where previously, each product would have a single price attribute, the product would now have price split out as follows:

  • price_us
  • price_gb
  • price_de
  • price — Maintain a default price using the standard attribute naming convention.

As each of these now represent the localised version of that attribute, the data within can be specific to that market.

This could look something like this:

[
  {
    "id":"KLAVIYO-TSHIRT1",
    "title":"Classic Klaviyo T-Shirt 1",
    "title_us":"Classic Klaviyo T-Shirt 1",
    "title_gb":"Classic Klaviyo T-Shirt 1",
    "title_de":"Klassisches Klaviyo-T-Shirt 1",
    "link":"https://klaviyogear_US.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1",
    "link_us":"https://klaviyogear_US.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1",
    "link_gb":"https://klaviyogear_GB.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1",
    "link_de":"https://klaviyogear_DE.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1",
    "description":"Standard issue for all Klaviyos. This t-shirt has the Klaviyo logo on the front and mark diagram on the back.",
    "description_US":"Standard issue for all Klaviyos. This t-shirt has the Klaviyo logo on the front and mark diagram on the back.",
    "description_GB":"Standard issue for all Klaviyos. This t-shirt has the Klaviyo logo on the front and mark diagram on the back.",
    "description_DE":"Standardausgabe für alle Klaviyos. Dieses T-Shirt hat das Klaviyo-Logo auf der Vorderseite und ein Markendiagramm auf der Rückseite.",
    "price":20,
    "price_us":20,
    "price_gb":15,
    "price_de":18,
    "currency": "USD",
    "currency_us": "USD",
    "currency_gb": "GBP",
    "currency_de": "EUR",
    "image_link":"https://www.klaviyo.com/media/images/examples/products/klaviyo-tshirt-thumbnail.png",
    "categories":["apparel","t-shirt","new-arrival","swag"],
    "inventory_quantity":190,
    "inventory_policy":1
  }
]

How to localise a Klaviyo template with this product data

By using the {% catalog lookup tag %}, you can build your product data as follows:

{% catalog "KLAVIYO-TSHIRT1" %}
  {{ catalog_item.metadata.title_de}}
{% endcatalog %}

Pros

  • Localised products are not required, all the product data will be found in the single product.
  • As this is now a single product, the reporting and data derived from it, will power global recommendations

Cons

  • Inventory management cannot be controlled by region
  • As all localised data is aggregated into a single product, it must all be contained within a single feed to prevent replacing product data as each product is loaded into Klaviyo
  • You cannot dynamically reference a localised product in a flow or a template. A campaign/Flow message for each market will need to be created.
  • Klaviyo product blocks will only support the default price and title fields. Custom product blocks will be needed.
  • As new languages/regions are added this will become bigger and harder to maintain

Option 3) — The Localised Attribute Product Model using JSON Objects

This approach also utilises the localised attribute product model, where each product within Klaviyo contains all the localisation data that you could need.

However, instead of creating multiple localised attributes, the data can be represented as an escaped JSON blob.

Why a JSON blob for attribute storage?

Using JSON blobs for localised attributes allows multiple benefits:

  • You can easily drop in a new market without needing to re-configure the feed
  • You can dynamically reference the localised attribute that is relevant to the profile directly within the template.

Where previously, each product would have a price attribute broken by market, this data can now be stored in the escaped JSON blob in a price_JSON property, while also maintaining a default price field for compatibility.

The JSON blob will now represent the localised version of that attribute, the data within can be specific to that market.

This could look something like this:

[
  {
    "id":"KLAVIYO-TSHIRT1",
    "title":"Classic Klaviyo T-Shirt 1",
    "title_JSON":"{\"us\":\"Classic Klaviyo T-Shirt 1\",\"gb\":\"Classic Klaviyo T-Shirt 1\",\"de\":\"Klassisches Klaviyo-T-Shirt 1\"}",
    "link":"https://klaviyogear_US.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1",
    "link_JSON":"{\"link_us\":\"https://klaviyogear_US.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1\",\"link_gb\":\"https://klaviyogear_GB.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1\",\"link_de\":\"https://klaviyogear_DE.myshopify.com/collections/klaviyo-classics/products/short-sleeve-t-shirt-1\"}",
    "description":"Standard issue for all Klaviyos. This t-shirt has the Klaviyo logo on the front and mark diagram on the back.",
    "description_JSON":"{\"description_US\":\"Standard issue for all Klaviyos. This t-shirt has the Klaviyo logo on the front and mark diagram on the back.\",\"description_GB\":\"Standard issue for all Klaviyos. This t-shirt has the Klaviyo logo on the front and mark diagram on the back.\",\"description_DE\":\"Standardausgabe für alle Klaviyos. Dieses T-Shirt hat das Klaviyo-Logo auf der Vorderseite und ein Markendiagramm auf der Rückseite.\"}",
    "price":20,
    "price_JSON":"{\"price_us\":20,\"price_gb\":15,\"price_de\":18}",
    "currency": "USD",
    "currenct_JSON":"{\"currency_us\": \"USD\",\"currency_gb\": \"GBP\",\"currency_de\": \"EUR\"}",
    "image_link":"https://www.klaviyo.com/media/images/examples/products/klaviyo-tshirt-thumbnail.png",
    "categories":["apparel","t-shirt","new-arrival","swag"],
    "inventory_quantity":190,
    "inventory_policy":1
  }
]

How to localise a Klaviyo template with this product data

By using the {% catalog lookup tag %}, you can build your product data as follows:

{% catalog "KLAVIYO-TSHIRT1" %}
  #person.site is an example profile property we use 
  #to indicate their store/region
  {% with site=person.site %}
    {{ catalog_item.metadata.title_JSON|string_to_object|lookup:site }}
  {% endwith %}
{% endcatalog %}

The {% with %} tag here allows you to create a dynamic variable which can be used to pull the correct localised messaging for the profile that will be sent the email, GB for example. By enabling this, a single template or universal content block can be created that can automatically be localised upon send.

Pros

  • Localised products are not required, all the product data will be found in the single product.
  • As this is now a single product, the reporting and data derived from it, will power global recommendations
  • You can easily drop in a new market without needing to re-configure the feed
  • You can dynamically reference the localised attribute that is relevant to the profile directly within the template.

Cons

  • Inventory management cannot be controlled by region
  • As all localised data is aggregated into a single product, it must all be contained within a single feed to prevent replacing product data as each product is loaded into Klaviyo

Bonus — How do I add localised availability to the feed?

When using a single product model, the localised data now sits within this single product, therefore, we can no longer use the inventory to manage availability between regions, as we could in the first example.

However, it is still possible to filter out products from recommendations by utilising Klaviyo categories. Categories can be filtered upon to create a product feed that belongs to that category to allow product filtering within campaigns.

How does this relate to localisation?

If we treat categories as ‘tags’, this changes the possibilities of how you can use product feeds. Simply by adding an availability tag such as available_gb to a product, this can then be added as a filter to a product feed to only display products that are available in GB.

We have a great article available to see how you can now build custom product blocks using these feeds. https://www.klaviyo.com/blog/solution-recipe-19-simplified-custom-product-blocks

Learn more!

If you’re interested in learning more about Klaviyo’s developer experience and capabilities, please visit developers.klaviyo.com!

Olaf
Olaf Dunn

Related content

For developers
Dec 22, 2023
Account Subscription History Solution Recipe

This Solution Recipe goes over how to extract historical data regarding a profile’s subscription timeline.

For developers
Dec 4, 2023
Solution Recipe: Using AI and APIs to create and upload images to your Klaviyo account

Solution Recipes are tutorials to achieve specific objectives in Klaviyo. They can also help you master Klaviyo, learn new third-party technologies, and come up with creative ideas. They are written mainly for developers and technically-advanced users. Note: We do our best to make sure any code and API references are accurate and current when this […]

For developers
Oct 24, 2023
Solution Recipe: Append, unappend, and unset custom properties programmatically with Klaviyo

Solution Recipes are tutorials to achieve specific objectives in Klaviyo. They can also help you master Klaviyo, learn new third-party technologies, and come up with creative ideas. They are written mainly for developers and technically-advanced users. Note: We do our best to make sure any code and API references are accurate and current when this […]