Blog / How to add a ‘read more/less’ feature for text blocks on Shopify

How to add a ‘read more/less’ feature for text blocks on Shopify

How to add a ‘read more/less’ feature for text blocks on Shopify
How to add a ‘read more/less’ feature for text blocks on Shopify

On-page content is a major part of SEO, particularly when it comes to category pages. Without text, search engines can struggle to understand what a page is about, which can make it difficult to rank well in search results.

However, if this text is too long it can push products down the screen, especially on mobile. This is not a great user experience.

One solution is a "read more/less" button. With Shopify though, implementing this isn’t always straightforward. One common approach is to create two separate text boxes for the condensed and extended versions of your text. While feasible, this method may require adding an extra metafield for the second block, resulting in a complicated and disorganized setup.

Alternatively, embedding HTML into your text box to handle the text versions can also lead to a cluttered outcome. Additionally, if your store contains a large number of products or collections that require individual editing, the process becomes even more troublesome.

Our Streamlined Approach

Our approach is a more streamlined solution requiring minor modifications to a Liquid file. This specifically targets the collection description.

  1. Locate the Liquid file containing the text you wish to split.
  2. Find the code displaying your collection description. It typically looks like this:
{{ collection.description }}

Wrap the above tag within the following HTML:

<div id="blink-collection-pad">
  <span id="blink-collection-desc" style="display:inline;">{{ collection.description }}</span>
  <span id="blink-links">
    <a href="#" class="blink-more" style="display:none;">Read more</a>
    <a href="#" class="blink-less" style="display:none;">Read less</a>
  </span>
</div>

This code embeds the ‘Read More’ and ‘Read Less’ links and provides class names and an ID for further manipulation.

Add Styles for Links

Add a few styles to format the links and set initial states. This can be done inline or within a separate CSS file. The CSS code should resemble:

<style>
  .blink-more, .blink-less { display: none; }
  #blink-collection-desc, #blink-links { display: inline; }
</style>

Configure JavaScript for Read More/Less

The final step involves adding a JavaScript script, which is explained in detail below. Ideally, include this in a separate JS file or inline. The script includes a couple of configurable variables:

var limit = 10;
var breakpoint = 1024;

The limit variable defines the word count before the ‘READ MORE’ button appears, hiding the remainder of the text until clicked.

The breakpoint variable sets the screen width at which the script starts functioning. For instance, to display the full text on desktop views but truncate on mobile, set the breakpoint to 1024 pixels. Consequently, when the screen width is 1025 pixels or wider, the full text is visible without a ‘READ MORE’ link. Conversely, for screen widths of 1024 pixels or less, the text is truncated.

The script is designed to ensure that it never breaks the text in the middle of a link, preserving any hrefs within your text without breaking the functionality.

Full Code

Here’s the complete HTML, CSS, and JavaScript to add the Read More/Less button to your Shopify collection description:

<style>
  .blink-more, .blink-less { display: none; }
  #blink-collection-desc, #blink-links { display: inline; }
</style>

<div id="blink-collection-pad">
  <span id="blink-collection-desc" style="display:inline;">{{ collection.description }}</span>
  <span id="blink-links">
    <a href="#" class="blink-more" style="display:none;">Read more</a>
    <a href="#" class="blink-less" style="display:none;">Read less</a>
  </span>
</div>
<script>
  function handleTextTruncation() {
    try {
      var outerContainerId = 'blink-collection-pad';
      var textContainerId = 'blink-collection-desc';
      var moreSelector = '.blink-more';
      var lessSelector = '.blink-less';
      var limit = 10;
      var breakpoint = 1024;

      var outercontainer = document.getElementById(outerContainerId);
      var container = document.getElementById(textContainerId);
      var originalText = container.innerHTML;
      var text = originalText.split(' ');
      var moreLink = document.querySelector(moreSelector);
      var lessLink = document.querySelector(lessSelector);

      function truncate() {
        var limitedText = '';
        if (window.innerWidth <= breakpoint) {
          var node = container.cloneNode(true);
          var words = node.textContent.split(' ');
          if (words.length > limit) {
            var currentWords = 0;
            var newText = document.createElement('div');
            for (var child of node.childNodes) {
              if (currentWords >= limit) break;
              if (child.nodeType === 3) {
                var childWords = child.textContent.split(' ');
                if (currentWords + childWords.length > limit) {
                  child.textContent = childWords.slice(0, limit - currentWords).join(' ') + '... ';
                }
                currentWords += childWords.length;
              } else {
                currentWords += child.textContent.split(' ').length;
              }
              newText.appendChild(child.cloneNode(true));
            }
            limitedText = new
Back to blog

Book A Meeting