Showing product recommendations on the product page using Liquid

This tutorial describes how to add product recommendations to the product page by using the Liquid recommendations object. For instructions specific to the Debut theme, see Showing product recommendations on the product page.

The recommendations object returns products only if it's used in a theme section that's rendered through an HTTP request to <base_url>?section_id=<section_id>&product_id=<product_id>. section_id is the ID of the section where the recommendations object is being used, and product_id is the ID of the product you want to show recommended products for. To determine the base_url, use the routes.product_recommendations_url attribute. Using the routes object rather than a hardcoded URL ensures that the product recommendations load in the correct locale.

This tutorial describes how to create a section to display recommendations and render it inside the product template of a theme.

Step 1: Create a product-recommendations.liquid section

  1. Create a new product-recommendations.liquid section, and replace all of its content with the code below:

    <div class="product-recommendations" data-base-url="{{ routes.product_recommendations_url }}" data-product-id="{{ product.id }}" data-limit="4">
      {%- if recommendations.products_count > 0 -%}
        <h2>You may also like</h2>
        <ul>
          {%- for product in recommendations.products -%}
          <li class="product">
            <a href="{{ product.url }}">
              <img class="product__img" src="{{ product.featured_image | img_url: '300x300' }}" alt="{{ product.featured_image.alt }}" />
              <p class="product__title">{{ product.title }}</p>
              <p class="product__price">{{ product.price | money}}</p>
            </a>
          </li>
          {%- endfor -%}
        </ul>
      {%- endif -%}
    </div>

    Add this code as well, which uses the {% javascript %} section tag:

    {% javascript %}
    var loadProductRecommendationsIntoSection = function() {
      // Look for an element with class 'product-recommendations'
      var productRecommendationsSection = document.querySelector(".product-recommendations");
      if (productRecommendationsSection === null) { return; }
      // Read product ID from data attribute
      var productId = productRecommendationsSection.dataset.productId;
      // Read base URL from data attribute
      var baseUrl = productRecommendationsSection.dataset.baseUrl;
      // Read limit from data attribute
      var limit = productRecommendationsSection.dataset.limit;
      // Build request URL
      var requestUrl = baseUrl + "?section_id=product-recommendations&product_id=" + productId + "&limit=" + limit;
      // Create request and submit it using Ajax
      var request = new XMLHttpRequest();
      request.open("GET", requestUrl);
      request.onload = function() {
        if (request.status >= 200 && request.status < 300) {
          var container = document.createElement("div");
          container.innerHTML = request.response;
          productRecommendationsSection.parentElement.innerHTML = container.querySelector(".product-recommendations").innerHTML;
        }
      };
      request.send();
    };
    // If your section has theme settings, the theme editor
    // reloads the section as you edit those settings. When that happens, the
    // recommendations need to be fetched again.
    // See https://help.shopify.com/en/themes/development/sections/integration-with-theme-editor
    document.addEventListener("shopify:section:load", function(event) {
      if (event.detail.sectionId === "product-recommendations") {
        loadProductRecommendationsIntoSection();
      }
    });
    // Fetching the recommendations on page load
    loadProductRecommendationsIntoSection();
    {% endjavascript %}

When the section is rendered with the page, recommendations.products_count is 0 and so the generated HTML is an empty div element:

<div class="product-recommendations" data-base-url="/recommendations/products" data-product-id="123" data-limit="4">
</div>

The JavaScript then loads the section at /recommendations/products?section_id=product-recommendations&limit=4&product_id=123. Since that endpoint returns a value for recommendations.products_count that isn't 0, the HTML for the recommendations is present in the response. The JavaScript takes that HTML and loads it into the empty container on the page.

If the user is using an alternate locale, the locale is included in the div's data-base-url:

<div class="product-recommendations" data-base-url="/fr/recommendations/products" data-product-id="123" data-limit="4">
</div>

Recommendations are also loaded using the alternate locale. For example, /fr/recommendations/products?section_id=product-recommendations&limit=4&product_id=123.

Step 2: Include the section in your product.liquid template

To display product recommendations at the bottom of the product page, include the section at the bottom of your templates/product.liquid file:

{% section 'product-recommendations' %}

Ready to start selling with Shopify?

Try it free