How to truncate both Collection and Product descriptions, AND titles. Code only works on one

Topic summary

A user is attempting to truncate both collection and product descriptions (and eventually titles) on their Shopify store, but their JavaScript code only works for one at a time.

The Problem:

  • Following an existing solution, they can truncate either product OR collection descriptions, but not both simultaneously
  • The issue appears to be in the theme.js file where element IDs are defined
  • Attempts to write multiple IDs or duplicate code blocks have failed

Proposed Solutions:

querySelector approach: Replace getElementById with querySelector using comma-separated selectors to target multiple IDs:

document.querySelector('#truncated-collection-description, #truncated-product-description')

Unified ID approach: Use the same ID for both collection and product descriptions instead of separate ones, though this raises concerns about ID uniqueness per page

HTML formatting consideration: Use strip_html filter before truncating to prevent broken HTML tags and maintain proper page structure. Some suggest strip_newlines as an alternative.

Resolution:
The original poster confirmed the querySelector solution worked successfully, allowing them to keep descriptions separated while preparing to also truncate titles.

Summarized with AI on November 24. AI used: claude-sonnet-4-5-20250929.

Hello, help please!

By following this solution:

https://community.shopify.com/c/shopify-design/collection-description-truncate-with-option-to-show-m…

I was able to successfully truncate EITHER the product description, OR the collections description. I’m trying to do both (and later also the title). I believe the problem is on the theme.js file, at the very end of the code page I have copied this:

let read_more = document.getElementById('read-more')
let read_less = document.getElementById('read-less');
let truncated_description = document.getElementById('truncated-collection-description');
let full_description = document.getElementById('collection-description');

read_more.addEventListener('click', showHideDescription)
read_less.addEventListener('click', showHideDescription)

function showHideDescription(){
  let ID = this.id
  if(ID === "read-more"){
    truncated_description.style.display = "none";
    full_description.style.display = "block";
  }else {
    truncated_description.style.display = "block";
    full_description.style.display = "none";    
  }
}

With this code, I can only write either (‘truncated-collection-description’) OR (‘truncated-product-description’), I don’t know how to write both, I’ve tried writing (‘truncated-collection-description’,‘truncated-product-description’) and (‘truncated-collection-description’),(‘truncated-product-description’), I’ve also tried duplicating this code block, each block with “product” and “collection”, nothing works.

Note this is on a test page, so I don’t have this code live.

Thank you so much in advance if anyone knows the solution.

@CluelessA

sorry for that issue this condition doesn’t work truncate properly can you please try anther way

try this way

https://codepen.io/dennisgarcia/pen/WvrReK

1 Like

You may try to replace

let truncated_description = document.getElementById('truncated-collection-description');
let full_description = document.getElementById('collection-description');

with

let truncated_description = 
   document.querySelector('#truncated-collection-description, #truncated-product-description');
let full_description = 
   document.querySelector('#collection-description, #product-description');

But why are you using those different IDs in the first place? Why not use the same id for both collection and product description?

Like


  {{ product.description | truncate: 40 }} Read more

    {{ product.description }} Read less

or


  {{ collection.description | truncate: 40 }} Read more

    {{ collection.description }} Read less

Then have this in CSS:

#full-description {
  display: none;
}

and this in JS:

let truncated_description = document.getElementById('truncated-description');
let full_description = document.getElementById('full-description');

This should work for both product and collection pages.

However, I have 2 warnings:

  1. ID should be unique per page, so you can’t have several elements with the same ID – keep this in mind if you’d want to use this code to, say, show article excerpts on blog pages;

  2. I do not like this code:

{{ product.description | truncate: 40 }}

Your description most probably have some HTML formatting. Consider the original description looks like:

 

 ...40 characters

The liquid code above will produce something like:


 ... 35-ish characters...

See how it breaks the HTML structure – your div and p tags are opened, but not closed here? This may break the look of your entire page.

So, I’d rather use this:

{{ product.description | strip_html | truncate: 40 }}

strip_html will convert your description to plain text before passing it to truncate and prevent this kind of problems.

1 Like

@tim_1 , you are amazing, you didn’t only give me the fish, but taught me also how to fish, # was the magic symbol I was missing, it worked!

As for why I didn’t use the same ID, I forgot to say that I did try that too, but for some reason it didn’t work either. Maybe I missed something important and if I tried the code you wrote it may work, but because next I want to try to truncate the titles too, I do prefer to keep them separated (specially since you mentioned that a page shouldn’t have different elements with the same ID).

As for the potential issue on how the descriptions are truncated, I understand what you mean, but for some reason what I have seems to be working well, the truncated descriptions are not doing anything crazy, this is the code I have for the product description, so far so good:


  {{ product.description | truncate: 1200 }} Read more

    {{ product.description }} Read less

I saw that actually if I add “| strip_html |” in there, it makes the whole description be plastered together when truncated, not what I’m going for.

All in all, thank you so much, your solution worked right away and you helped me immensely!

{{ product.description | strip_html | truncate: 400 }}

replay with

{{ product.description | strip_newlines | truncate: 400 }}