How to Show Recently Viewed Products in Shopify (Step-by-Step Guide)

Want to improve customer experience and boost your sales on Shopify? One powerful way is to show recently viewed products to your visitors.

By default, Shopify shows “You May Also Like” or recommended products based on tags or product titles — but what if you want to remind customers of the exact items they previously viewed?

This blog will show you how to add a “Recently Viewed Products” section in your Shopify store using a custom code snippet.

🔧 Why Show Recently Viewed Products?

Displaying recently viewed products:

  • Helps customers easily return to previously visited items
  • Reduces friction in the buying process
  • Increases chances of conversion
  • Enhances the overall shopping experience

🪄 Step-by-Step Guide to Add Recently Viewed Products in Shopify

✅ Step 1: Go to Your Shopify Theme

  1. Log in to your Shopify admin.
  2. Navigate to Online Store > Themes.
  3. Choose the theme you want to edit.
  4. Click on the three dots (⋮) next to the theme and select Edit Code.

📁 Step 2: Create a New Section

  1. Inside the Sections folder, click Add a new section.
  2. Name it something like: recently-viewed-products.liquid.
  3. Now, paste the code you get below one line
  4. Click Save.
{% comment %}
  Recently Viewed Products Section
{% endcomment %}

<div class="recently-viewed-section page-width">
  {% if section.settings.title != blank %}
    <h2 class="rvp-title">{{ section.settings.title }}</h2>
  {% endif %}
  <div id="recently-viewed-products" class="recently-viewed-products"></div>
  <div id="no-recently-viewed" class="rvp-empty-message" style="display: none;">
    <p>No recently viewed products yet. Start browsing our collection!</p>
    <a href="/collections/all" class="rvp-button">Browse Now</a>
  </div>
</div>

<style>
  .recently-viewed-section {
    margin-top: 60px;
    padding: 20px;
    background-color: #fafafa;
    border-radius: 8px;
  }

  .rvp-title {
    font-size: 2rem;
    margin-bottom: 30px;
    padding-bottom: 10px;
    border-bottom: 2px solid #e0e0e0;
    font-weight: 700;
    color: #222;
  }

.recently-viewed-products {
  display: flex;
  gap: 24px;
  justify-content: flex-start;
  overflow-x: auto; /* important for scrollbars */
  padding-bottom: 10px;

  /* Hide scroll buttons on WebKit */
  scrollbar-width: thin; /* for Firefox */
  scrollbar-color: #ccc transparent;
}

.recently-viewed-products::-webkit-scrollbar {
  height: 8px; /* show horizontal scrollbar */
}

.recently-viewed-products::-webkit-scrollbar-thumb {
  background-color: #ccc; /* scrollbar handle */
  border-radius: 4px;
}

.recently-viewed-products::-webkit-scrollbar-button {
  display: none; /* hide the scroll arrows */
}


  .recently-viewed-item {
    width: 180px;
    min-width: 180px;
    text-align: left;
    background: #fff;
    border: 1px solid #e5e5e5;
    border-radius: 10px;
    padding: 15px;
    box-shadow: 0 2px 6px rgba(0,0,0,0.05);
    transition: transform 0.2s ease, box-shadow 0.3s ease;
  }

  .recently-viewed-item:hover {
    transform: translateY(-4px);
    box-shadow: 0 6px 18px rgba(0,0,0,0.1);
  }

  .recently-viewed-item img {
    width: 100%;
    height: auto;
    border-radius: 8px;
    margin-bottom: 12px;
  }

  .recently-viewed-item p {
    margin: 4px 0;
    font-size: 0.95rem;
    color: #444;
  }

  .recently-viewed-item .price {
    font-weight: 600;
    font-size: 1rem;
    color: #d32f2f;
  }

  .rvp-empty-message {
    text-align: center;
    font-size: 1.1rem;
    padding: 40px;
    background: linear-gradient(135deg, #fefefe, #f3f3f3);
    border: 2px dashed #ccc;
    border-radius: 10px;
    color: #555;
    margin-top: 30px;
  }
  .rvp-button {
  display: inline-block;
  margin-top: 15px;
  padding: 10px 20px;
  background-color: #0077cc;
  color: #fff;
  border-radius: 4px;
  text-decoration: none;
  transition: background-color 0.3s;
}

.rvp-button:hover {
  background-color: #005fa3;
}


  @media screen and (max-width: 768px) {
    .recently-viewed-item {
      min-width: 47%;
    }
  }

  @media screen and (max-width: 480px) {
    .recently-viewed-item {
      /* width: 100%; */
    }
  }
</style>

<script>
  (function() {
    const maxViewed = {{ section.settings.max_products }};
    const productHandle = "{{ product.handle }}";
    const productTitle = "{{ product.title | escape }}";
    const productImage = "{{ product.featured_image | img_url: '200x' }}";
    const productUrl = "{{ product.url }}";
    const productPrice = {{ product.price | money_without_trailing_zeros | json }};

    let viewedProducts = JSON.parse(localStorage.getItem('recently_viewed')) || [];

    // Remove current product if exists
    viewedProducts = viewedProducts.filter(p => p.handle !== productHandle);

    // Add current product to the top
    viewedProducts.unshift({
      handle: productHandle,
      title: productTitle,
      image: productImage,
      url: productUrl,
      price: productPrice
    });

    // Limit to max number
    viewedProducts = viewedProducts.slice(0, maxViewed);
    localStorage.setItem('recently_viewed', JSON.stringify(viewedProducts));

    const container = document.getElementById('recently-viewed-products');
    const emptyMessage = document.getElementById('no-recently-viewed');

    if (container) {
      const itemsToShow = viewedProducts.slice(1); // exclude current product

      if (itemsToShow.length === 0) {
        emptyMessage.style.display = 'block';
      } else {
        itemsToShow.forEach(p => {
          const el = document.createElement('div');
          el.className = 'recently-viewed-item';
          el.innerHTML = `
            <a href="${p.url}">
             <img src="${p.image}" alt="${p.title}" loading="lazy">
              <p>${p.title}</p>
              <p class="price">${p.price}</p>
            </a>
          `;
          container.appendChild(el);
        });
      }
    }
  })();
</script>

{% schema %}
{
  "name": "Recently Viewed Products",
  "tag": "section",
  "settings": [
    {
      "type": "text",
      "id": "title",
      "label": "Section title",
      "default": "Recently Viewed Products"
    },
    {
      "type": "range",
      "id": "max_products",
      "label": "Maximum products to store",
      "min": 2,
      "max": 12,
      "step": 1,
      "default": 6
    }
  ],
  "presets": [
    {
      "name": "Recently Viewed Products"
    }
  ]
}
{% endschema %}

🧱 Step 3: Add the Section to Your Product Page

  1. Go to Online Store > Customize for the theme you just edited.
  2. Open the default product template.
  3. Scroll to the position where you want to show the recently viewed products — usually below the product description or above related products.
  4. Click Add Section and select the name you gave earlier.
  5. Click Save.

👁️‍🗨️ How It Works

Once implemented:

  • Customers will start seeing the products they recently visited.
  • As you navigate through products, each one will appear in the “Recently Viewed” section.
  • The section is fully responsive and customizable via CSS or Liquid code.

You can also:

  • Change the design layout
  • Modify styling and spacing
  • Reorder the placement of this section on the product page

🧑‍🎨 Want to Customize Further?

Feel free to edit the section:

  • Change styling like background, font size, borders, etc.
  • Modify number of products shown
  • Add animations or transitions for smoother UI