(Squarespace) How to add Category above Product Name in Shop Page

To add Category above Product Name in Shop Page, like this.

#1. Use this code to Custom CSS

/* product categories */
.product-category-name {
  font-size: 12px !important;
  margin-bottom: 4px !important;
  line-height: 1.2 !important;
  transition: all 0.2s ease !important;
  padding: 3px 8px !important;
  border-radius: 10px !important;
  display: inline-block !important;
  animation: fadeInCategory 0.3s ease-out !important;
  background-color: #fff;
}
.product-list-item:hover .product-category-name {
  transform: translateY(-1px) !important;
}
@media (max-width: 768px) {
  .product-category-name {
    font-size: 8px !important;
    margin-bottom: 3px !important;
    padding: 2px 6px !important;
  }
}
@keyframes fadeInCategory {
  from {
    opacity: 0;
    transform: translateY(-5px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

#2. Use this code to Shop Page Header Injection

<script>
document.addEventListener('DOMContentLoaded', function() {
  
  setTimeout(function() {
    addCategoryToProducts();
  }, 800);
  
  function addCategoryToProducts() {
    const layoutType = getLayoutType();
    let activeCategory = null;
    let categories = [];
    
    if (layoutType === 'sidebar') {
      activeCategory = document.querySelector('.category-link.active');
      const categoryLinks = document.querySelectorAll('.nested-category-tree-wrapper .category-link');
      categoryLinks.forEach(link => {
        if (!link.classList.contains('active') && link.textContent.trim() !== 'All') {
          categories.push({
            name: link.textContent.trim(),
            url: link.getAttribute('href')
          });
        }
      });
    } else if (layoutType === 'top') {
      activeCategory = document.querySelector('.nested-category-breadcrumb-link.bold');
      const categoryLinks = document.querySelectorAll('.nested-category-breadcrumb-link');
      categoryLinks.forEach(link => {
        if (!link.classList.contains('bold') && link.textContent.trim() !== 'All') {
          categories.push({
            name: link.textContent.trim(),
            url: link.getAttribute('href')
          });
        }
      });
    }
    
    if (activeCategory && activeCategory.textContent.trim() !== 'All') {
      const categoryName = activeCategory.textContent.trim();
      const productItems = document.querySelectorAll('.product-list-item');
      
      productItems.forEach((productItem, index) => {
        setTimeout(() => {
          const titleElement = productItem.querySelector('.product-list-item-title');
          
          if (titleElement && !productItem.querySelector('.product-category-name')) {
            const categoryElement = document.createElement('div');
            categoryElement.className = 'product-category-name';
            categoryElement.textContent = categoryName;
            categoryElement.setAttribute('data-category', categoryName);
            
            titleElement.parentNode.insertBefore(categoryElement, titleElement);
          }
        }, index * 100);
      });
    } else if (categories.length > 0) {
      const productItems = document.querySelectorAll('.product-list-item');
      
      productItems.forEach((productItem, index) => {
        setTimeout(() => {
          checkProductCategory(productItem, categories);
        }, index * 300);
      });
    }
  }
  
  function getLayoutType() {
    const layoutElement = document.querySelector('[data-category-display-type]');
    if (layoutElement) {
      const displayType = layoutElement.getAttribute('data-category-display-type');
      return displayType === 'sidebar' ? 'sidebar' : 'top';
    }
    
    if (document.querySelector('.nested-category-tree-wrapper')) {
      return 'sidebar';
    } else if (document.querySelector('.nested-category-children')) {
      return 'top';
    }
    
    return 'unknown';
  }
  
  async function checkProductCategory(productItem, categories) {
    const productLink = productItem.querySelector('.product-list-item-link');
    const titleElement = productItem.querySelector('.product-list-item-title');
    
    if (!productLink || !titleElement || productItem.querySelector('.product-category-name')) {
      return;
    }
    
    const productUrl = productLink.getAttribute('href');
    
    for (let category of categories) {
      try {
        const response = await fetch(category.url + '?format=json');
        const data = await response.json();
        
        if (data.items && data.items.length > 0) {
          const productExists = data.items.some(item => {
            return item.fullUrl === productUrl || 
                   productUrl.includes(item.urlId) ||
                   item.fullUrl.includes(productUrl.split('/').pop());
          });
          
          if (productExists) {
            const categoryElement = document.createElement('div');
            categoryElement.className = 'product-category-name';
            categoryElement.textContent = category.name;
            categoryElement.setAttribute('data-category', category.name);
            
            titleElement.parentNode.insertBefore(categoryElement, titleElement);
            break;
          }
        }
      } catch (error) {
        console.log('Error checking category:', category.name, error);
      }
    }
  }
  
});
</script>

1 Like