Quickstart: Customizing the Recco.js UI with templates

Introduction

This guide is for users who have a basic Recco.js integration and want to customize the visual appearance of their recommendation widgets. While the default 'luigis' theme provides a clean look, you will likely want to modify the HTML structure to perfectly match your website's branding and styles. Recco.js uses a powerful templating system based on Vue.js, allowing you to take full control over the rendered HTML. By the end of this guide, you will know how to override the default templates to create a fully custom design for your recommendations.

What you'll learn

  • How to identify and override the two main Recco.js templates.
  • How to access and display product data (like title, image, and price) within your custom template.
  • How to create unique templates for different recommendation widgets on your site.

Who is this guide for

  • Developers who want to seamlessly integrate the look and feel of recommendation widgets with their existing site design.
  • Users who need to display custom product attributes in their recommendations.

Prerequisites

Before you start, please ensure you have the following in place:

  • A working basic integration of Recco.js as covered in the first guide.
  • Your Luigi's Box TrackerId.
  • The ability to edit the HTML of the page where the recommender is located.

Step-by-step: Customizing templates

Step 1: Understand the core templates

Recco.js uses two primary templates to render a widget:

  1. #template-recommend: This is the main container or wrapper for the entire widget. It typically includes a title and the loop that renders each item.
  2. #template-recommend-item: This is the template for a single recommended product. This is the template you will customize most often.

To override them, you simply define a <script> tag with the corresponding id and type="text/x-template" anywhere in your HTML, before the script that initializes Luigis.Recommend.

Step 2: Create a custom item template

Let's start by creating a custom design for a single product card. In this example, we will display the product's image, title, brand, and price. You can access all product data through the item object, primarily within item.attributes.

Example: Custom #template-recommend-item

<!-- 
  Place this template script anywhere in your HTML before the Recco.js initialization script.
-->
<script type="text/x-template" id="template-recommend-item">
  <div class="product-card-custom">
    <a :href="item.url">
      <img 
        :src="item.attributes.image_link || 'https://placehold.co/400x400/eee/ccc?text=No+Image'" 
        :alt="item.attributes.title"
        class="product-image-custom"
      >
    </a>
    <div class="product-info-custom">
      <h3 class="product-title-custom">{{ item.attributes.title }}</h3>
      <p class="product-brand-custom" v-if="item.attributes.brand">{{ item.attributes.brand[0] }}</p>
      <div class="product-price-custom" v-if="item.attributes.price_amount">
        {{ item.attributes.price_amount | price }}
      </div>
    </div>
  </div>
</script>

Key template features:

  • Data binding: Use {{ variable }} for text and :attribute="variable" (shorthand for v-bind:attribute) for HTML attributes.
  • Conditionals: Use v-if to only render an element if the data exists (e.g., v-if="item.attributes.brand").
  • Fallbacks: Use the || operator to provide a default value, like a placeholder image.
  • Price Filter: The | price filter automatically formats the price number with the correct currency symbol and decimals.

Step 3: Customize the main container (optional)

You can also customize the main wrapper. For example, you might want to add a custom title or change the list structure from <div>s to a <ul>. The main template must include the <recommend-item> component, which will automatically use your custom #template-recommend-item template.

Example: Custom #template-recommend

<script type="text/x-template" id="template-recommend">
  <div class="recommendation-widget-custom">
    <h2>You Might Also Like</h2>
    <div class="products-grid-custom">
      <recommend-item
        v-for="item in items"
        :key="item.url"
        :item="item"
      ></recommend-item>
    </div>
  </div>
</script>

Step 4: Use specific templates for different widgets

If you are using Batch Mode to display multiple recommenders, you can give each one a unique design. This is done by adding a suffix to the template id that matches the Name you provided in the configuration.

If you have a recommender named 'alternatives', Recco.js will look for #template-recommend-item-alternatives first, before falling back to the default #template-recommend-item.

Example: A specific template for a "complements" widget

// From your BatchRecommenders settings...
{
  Name: 'complements',
  Type: 'item_detail_complements',
  // ... other settings
}

Example: HTML structure

<!-- This template will ONLY be used by the 'complements' recommender -->
<script type="text/x-template" id="template-recommend-item-complements">
  <div class="complement-item-small">
    <a :href="item.url">
      <img :src="item.attributes.image_link">
      <span>{{ item.attributes.title }}</span>
    </a>
  </div>
</script>

Best practices

  • Define templates first: Always place your <script type="text/x-template"> tags in the HTML before the <script> tag that calls Luigis.Recommend. If the templates aren't present when the library initializes, it will use its internal defaults.
  • Style with classes: Use your own CSS classes in the templates. This is the easiest way to ensure the widgets match your site's existing styles.
  • Be robust: Always check if data exists with v-if or provide fallbacks to prevent errors and ensure your layout doesn't break if a product is missing a specific attribute.

Next steps

  • Localize content: Learn how to use the Translations and PriceFilter options to display your recommendations in different languages and currencies.
  • Implement a carousel: Now that you control the HTML, learn how to easily convert your list into an interactive slider by reading this section.