Breadcrumb path

Hi All,

I’m trying to make the breadcrumb on my product page show the whole path rather than just Home/Product page. I contacted customer support who told me:

To have the breadcrumbs show custom information, you can use Velo code. Specifically, you can set custom values using items property.

Since you only want to change the structure on the nested pages, like product page, you can only write the code on those pages’ Velo panel. To get the current product data, use getProduct () function. To access the collection name of the product, you can query () the Stores/products database and include () the collections referenced items.

My current code looks as follows:

$w . onReady ( function () {
$w ( ‘#productPage1’ ). getProduct ()
. then (( product ) => {
let productName = product . name ;
let productDescription = product . description ;
// see example product object below
})
. catch (( error ) => {
console . error ( error );
});

wixData . query ( “Stores/Products” )
. include ( “collections” )
. find ()
. then (( results ) => {
let collection = results ;
if ( results . items . length > 0 ) {
console . log ( results . items [ 0 ]); //see item below
} else {
// handle case where no matching items found
}
})
. catch (( err ) => {
console . log ( err );
});

let breadcrumbItems = $w ( ‘#breadcrumbs1’ ). items ;
let productName = breadcrumbItems [0]. label ;
let collection = breadcrumbItems [1]. label ;
$w ( ‘#breadcrumbs1’ ). items
});

I have tried to tinker with the code as much as I could to get it to work but I am at my end wits’ end.

Any help would be greatly appreciated!

Hi Frederik! Could you post a link to your editor so I can take a look at your setup?

And from what I understand, you’d like the breadcrumbs to read: Home > Collection Name > Product Name, is that correct?

Also regarding this section of your code:

let breadcrumbItems = $w('#breadcrumbs1').items;
let productName = breadcrumbItems[0].label;
let collection = breadcrumbItems [1].label; 
$w('#breadcrumbs1').items

Here, you’re not really changing anything to breadCrumbItems, and the productName and collection variables are unused. Take a look at the last example in the items section (the one titled “Set breadcrumbs items for dynamic pages using Wix Location”), and see if that helps too.

Hi Emmy,

Your absolutely correct, I want the path to be Home > Collection Name > Product Name.

I figured there was something wrong with the last part of the code as I don’t fully understand how to use the get breadcrumbs Item function (my coding skills aren’t that great :grimacing:)

I’m trying to implement the “Set breadcrumbs items for dynamic pages using Wix Location” as suggested but I’m struggling to understand how to code works and how I can use the Getproduct function from earlier and the collection name in there and what words to replace.

How do I share a link to my editor? Is it simply copying the html of the page I am editing?

Many thanks for helping me out and sorry for all the questions :sweat_smile:

Yup, copying the editor link is fine!

Hey again,

Played around with the breadcrumbs API and I’d do something like this:

import wixData from 'wix-data';

$w.onReady(async function () {
    let product = await $w('#productPage1').getProduct();
    let collection = await getCurrentCollection(product);
    
    //Sets the breadcrumb values.
    $w('#breadcrumbs1').items = [{ 'label': 'Home', 'link': '/' },
        { 'label': collection.name.toString(), 'link': '/' + collection.name.toString() },
        { 'label': product.name.toString(), 'isCurrent': true },
    ];
});

async function getCurrentCollection(productName) {
    let collection;
    const collectionPromise = wixData.queryReferenced("Stores/Products", productName, "collections")
        .then((results) => {
            if (results.items.length > 0) {
                //product can have multiple collections. this will only assume you want the first one.
                collection = results.items[0]; 
            } else {
                // handle case where no matching items found
                console.log('error getting collection');
            }
        });
    await Promise.resolve(collectionPromise);
    return collection;
}

Basically, you’ll want to get your current product’s name, use that to get the collection’s name, and then set your breadcrumb values to link to Home > Collection > Product.

However, this is assuming that each Product only belongs to one collection – if you have something more complex, you’ll want to tweak this! It also assumes that the URL for the previous page is just www.[your-domain.com]/collection.name.toString() , so you’ll have to change that accordingly if it’s different.

Also remember to make your $w.onReady function async if you’re working with Promises!

Hi Emmy,

Thank you so much, this works perfectly😁!

The only remaining issue is that the collection page name does not change depending on the language. e.g. the Dutch collection name will show even if the user switched to English. I have translated the collection names.

Any help on this would be great,

Many thanks

Hi Emmy,

Sorry to bother you again. I noticed that when I click on the collection in the breadcrumb the html shows the collection beginning with a Capital letter. I believe this is because the collection field is also with a capital letter. However, the page of the collection is not with a capital letter redirecting a user to a 404 page. I can change all the collections to lower cases to so that the html matches the page.

I was hoping if there was a way to convert the collection to a lower case. Would tostring().tolowercase() work?

Many thanks again :grin:

Converting the string to lowercase would work!

Hmm, I see your issue – the solution I gave you would assume your link corresponds directly to the Collection’s name, but I know that’s not always the case.

Maybe something you could instead do is to use session storage to keep track of the name of the product page. Instead of in a local variable, you could store the breadcrumb values in session storage. For example, when the user’s on a product page, store the Product label and link in a breadcrumbs JSON as a variable. in session storage.

Here’s a similar issue in the forums:

Hi Emmy,

Thanks for the response,

I managed to turn the html to lowercase which was the easy part😅.

I’m trying to implement the solution from the link you provided and getting the collection name as a variable to implement it in the breadcrumb but I’m not really getting anywhere. I think my biggest problem is that I’m not really sure what i’m looking at or how to implement it.

Following the steps from the link I managed to have a text element display the path which comes from the JSON storage. But I don’t know how to extract only the collection path and implement that in the breadcrumb.

Many thanks again for all your help :grin:

Hi Frederik!

Any luck so far? If not, let me know what parts specifically aren’t making sense.
You’ll have to familiarize yourself with session storage . The idea is that if a user is on a product page, you store the product’s name (using data from the page, like the title or something) as the second breadcrumb path, and the current page they’re on as the third path.

Hi Emmy,

Looking at the example provided, https://www.wix.com/velo/forum/coding-with-velo/create-a-breadcrumb-trail-with-wix-code I understand what’s happening but don’t know how to edit it so that I can retrieve the collection and place it in the breadcrumb.

If i’m not mistaken this captures the users session in a Json:

import wixLocation from ‘wix-location’ ;
import { session } from ‘wix-storage’ ;
$w . onReady ( function (){ let path = wixLocation . path
let sBreadtrail = session . getItem ( ‘breadtrail’ )
if ( sBreadtrail !== null )
{ let aBreadtrail = JSON . parse ( sBreadtrail );
aBreadtrail . push ( path );
sBreadtrail = JSON . stringify ( aBreadtrail );
} else { sBreadtrail = JSON . stringify ([ path ]);
} session . setItem ( ‘breadtrail’ , sBreadtrail );});

And with the following code I am able to display the pages the users visited:

import {session} from ‘wix-storage’

$w.onReady( function () {
let variable = JSON.parse(session.getItem(‘breadtrail’));
let path = variable.join(" > “); $w(” #Breadcrumb ").text = path; });

What i’m really struggling with is extracting the collection page a user visited and capture it in the breadcrumb. I tried let variable = JSON . parse ( session . getItem ( ‘breadtrail’ )). getCurrentCollection
But that didn’t work.

What doesn’t make sense to me is how from the Json parse I can write a code so that I can store the visited collection page as a variable and add it to the breadcrumb.

Thank again for all the help :grin:

Hi Emmy,

Would it be easier to keep everything as it is but only change the link to the collection to the previous URL considering that that is where the user will come from?

I found this code:

import wixLocation from ‘wix-location’ ;

import { session } from ‘wix-storage’ ;

let previousPageURL ;

$w . onReady ( function () {
previousPageURL = session . getItem ( “page” );
session . setItem ( “page” , wixLocation . url );
});

However, inserting the previousPageURL in the breadcrumb as follow:

$w ( ‘#breadcrumbs1’ ). items = [{ ‘label’ : ‘Home’ , ‘link’ : ‘/’ },
{ ‘label’ : collection . name . toString (), ‘link’ : previousPageURL },
{ ‘label’ : product . name . toString (), ‘isCurrent’ : true },
];
});

Does not work. Any thoughts?