Shop breadcrumbs navigation
A while ago, before I learned how to code it myself, I purchased a plug-in extension to have more sophisticated breadcrumb navigation in my shop. Its main functionality allows visitors to navigate back to the category of the product they are viewing. It functions great and I have no complaints concerning it, apart from two: the code provided was obfuscated, and a pesky console log was always present informing me and everyone else that I am using this certain extension/plug-in. I decided to get rid of it. Before we continue let me warn you - the commercial extension is probably a better way of doing this. It has support and if you are not into coding it remains the go-to for this functionality. Below, however, you will find my custom implementation which I coded from scratch. I have no idea how the commercial extension did this, but I fetched two JSON files and read the required information from there. First I dynamically construct a map of my shop categories. This means that I get their ID, display name and URL. Second I get the second JSON of the product you are viewing and get the category ID from there. Then I compare the two and construct an HTML structure to embed into my product page. I will not be posting this solution anywhere else, to not take away business from people who devised a probably better way of doing the same thing, so use this for learning purposes.
HTML:
JAVASCRIPT: <script> document.addEventListener('DOMContentLoaded', function () { const subStringTwo = 'shop/p/'; const getURL = window.location.href; if (getURL.includes(subStringTwo)) { //fetch the json data const productJsonUrl = getURL + '?format=json-pretty'; const categoryJsonUrl = '/shop?format=json-pretty'; Promise.all([ fetch(categoryJsonUrl).then(response => response.json()), fetch(productJsonUrl).then(response => response.json()) ]) // Construct category names and URLs from IDs .then(([categoryData, productData]) => { function createCategoryMap(categories) { const categoryMap = {}; categories.forEach(category => { categoryMap[category.id] = { name: category.displayName, url: category.fullUrl }; }); return categoryMap; } function getCategoryInfoById(categoryId, categoryMap) { return categoryMap[categoryId] || { name: 'Unknown Category', url: '#' }; } const nestedCategories = categoryData.nestedCategories; const categories = nestedCategories.categories; const categoryMap = createCategoryMap(categories); function extractCategoryId(hierarchicalId) { const parts = hierarchicalId.split('>'); return parts[parts.length - 1]; } const productCategoryId = productData.item.categoryIds[0]; const { name: categoryName, url: categoryUrl } = getCategoryInfoById(productCategoryId, categoryMap); // Create HTML elements const mainCategoryName = categoryData.collection.title; const productName = productData.item.title; const breadcrumbContainer = document.createElement('div'); breadcrumbContainer.className = 'custom-breadcrumb-container'; const mainCategoryElement = document.createElement('span'); mainCategoryElement.className = 'custom-breadcrumb-main-category'; mainCategoryElement.textContent = mainCategoryName; mainCategoryElement.addEventListener('click', function () { window.location.href = '/shop'; }); const separator1 = document.createElement('div'); separator1.className = 'custom-breadcrumb-separator'; const categoryElement = document.createElement('span'); categoryElement.className = 'custom-breadcrumb-category'; categoryElement.textContent = categoryName; categoryElement.addEventListener('click', function () { window.location.href = categoryUrl; }); const separator2 = document.createElement('div'); separator2.className = 'custom-breadcrumb-separator'; const productElement = document.createElement('span'); productElement.className = 'custom-breadcrumb-product'; productElement.textContent = productName; productElement.addEventListener('click', function () { window.location.href = getURL; }); //get rid of stock crumbs and append custom ones const oldBreadcrumbContainer = document.querySelector('.ProductItem-nav'); if (oldBreadcrumbContainer){ oldBreadcrumbContainer.remove(); } breadcrumbContainer.appendChild(mainCategoryElement); breadcrumbContainer.appendChild(separator1); breadcrumbContainer.appendChild(categoryElement); breadcrumbContainer.appendChild(separator2); breadcrumbContainer.appendChild(productElement); const productBlock = document.querySelector('.ProductItem'); productBlock.prepend(breadcrumbContainer); }) .catch(error => { console.error('Error fetching data:', error); }); } }); </script>
CSS: .custom-breadcrumb-container { display: flex; align-items: center; margin: 10px 0; } .custom-breadcrumb-main-category, .custom-breadcrumb-category, .custom-breadcrumb-product { margin-right: 15px; cursor: pointer; letter-spacing: 1.7px; font-size: 25px; } .custom-breadcrumb-separator { width: 22px; height: 22px; margin: 0; background-size: contain; background-position: center; background-repeat: no-repeat; background-image: url(https://images.squarespace-cdn.com/content/v1/6654b2fee26f292de13f1a9d/0807b231-9516-4451-946f-ca9bc16dd8c2/starIcon1.png); pointer-events: auto; cursor: default; margin-right: 15px; margin-top: -5px; transition: all 2s ease; } .custom-breadcrumb-separator:hover { transform: rotate(360deg); } .custom-breadcrumb-link { text-decoration: none; color: #000; } .custom-breadcrumb-link:hover { text-decoration: underline; }
Javascript goes into the footer section. Also this post is not a hint to finding the hidden shop, look elsewhere adventurer, ask the warden perhaps.
COMMENTS:
Leave a comment: