Last active
April 9, 2025 10:58
-
-
Save sandipklevu/6660115e410c512334099fbbc9f15faf to your computer and use it in GitHub Desktop.
Klevu Template Custom Price Fetch from BigCommerce
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script type="text/javascript"> | |
var klevuIdsWithKeys = []; | |
klevu.interactive(function () { | |
function formatPrice(price, currency, locale = navigator.language) { | |
return new Intl.NumberFormat(locale, {style: 'currency', currency: currency}).format(price); | |
} | |
function findProductList(data) { | |
return data.find(item => item.id === 'productList'); | |
} | |
function clearElementsById(elements) { | |
elements.forEach((element) => { | |
if (typeof element === 'string') { | |
element = document.getElementById(element); | |
} | |
if (element) { | |
element.innerHTML = ''; | |
} | |
}); | |
} | |
function cleanUpProductId(id) { | |
if (typeof id === 'undefined' || id === '') { | |
return false; | |
} | |
let pid = id.toUpperCase(); | |
if (pid.indexOf('-') !== -1) { | |
pid = pid.split('-')[0]; | |
} | |
return pid; | |
} | |
function fetchPrices(klevuIds, callback) { | |
const finalEntIds = []; | |
let bcId = ''; | |
klevuIds.forEach(function (id) { | |
bcId = cleanUpProductId(id); | |
finalEntIds.push(bcId); | |
klevuIdsWithKeys.push(bcId); | |
}); | |
console.log('finalIds before request to BC: '+ finalEntIds); | |
fetch('/graphql', { | |
method: 'POST', | |
credentials: 'same-origin', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer {{ settings.storefront_api.token }}' // use auto-generated token | |
}, | |
body: JSON.stringify({ | |
query: `query FetchGroupPrices { | |
site { | |
products(entityIds:[` + finalEntIds + `],first:50){ | |
edges { | |
node { | |
id | |
entityId | |
sku | |
prices(currencyCode: {{currency_selector.active_currency_code}}) { | |
price { | |
...PriceFields | |
} | |
salePrice { | |
...PriceFields | |
} | |
basePrice { | |
...PriceFields | |
} | |
retailPrice { | |
...PriceFields | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
fragment PriceFields on Money { | |
currencyCode | |
value | |
}` | |
}) | |
}) | |
.then(res => res.json()) | |
.then(callback) | |
.catch(error => console.error(error)); | |
} | |
function renderPricesOnFrontend( | |
result, | |
productList, | |
priceSelector, | |
listItemSelector, | |
country, | |
currency | |
) { | |
if (!result.data) { | |
return; | |
} | |
const priceBeforeDiscountSelector = priceSelector.replace('Sale', 'Orig'); | |
const helpers = klevu.search.base.getScope().template.getHelpers(); | |
const resNodes = result.data.site.products.edges || {}; | |
if (!resNodes) { | |
return; | |
} | |
helpers.clearElementsById(document.querySelectorAll(priceSelector)); | |
helpers.clearElementsById(document.querySelectorAll(priceBeforeDiscountSelector)); | |
var idx = 0; | |
const resultObject = resNodes; | |
// Loop through all the items from the current Klevu response | |
for (const currentProduct of productList) { | |
const {id: product_id} = currentProduct; | |
var klevuPId = cleanUpProductId(product_id).toString(); | |
// return if the product is excluded from the store and there's no data for it | |
if (resultObject[idx].node['entityId'] === null) continue; | |
resultObject.forEach(item => { | |
const bEntityId = item.node.entityId.toString(); | |
if (bEntityId === klevuPId) { | |
const bcPrices = item.node['prices']; | |
if (!bcPrices) { | |
return; | |
} | |
const basePrice = bcPrices.basePrice && bcPrices.basePrice.value != null ? bcPrices.basePrice.value : null; | |
const price = bcPrices.price && bcPrices.price.value != null ? bcPrices.price.value : null; | |
const salePrice = bcPrices.salePrice && bcPrices.salePrice.value != null ? bcPrices.salePrice.value : null; | |
const label = ''; | |
// Now, we are selecting the proper elements by ID and grab prices from our POST request | |
const listPriceItems = document.querySelectorAll(`${listItemSelector}[data-id="${product_id}"]`); // our parent element, referring by ID | |
[...listPriceItems].forEach((list) => { | |
const salePriceItem = list.querySelector(priceSelector); | |
const origPriceItem = list.querySelector(priceBeforeDiscountSelector); | |
domModifyPriceChange(salePriceItem, origPriceItem); | |
}); | |
function domModifyPriceChange(salePriceItem, origPriceItem) { | |
if (price === null) return; | |
const priceFinal = helpers.formatPrice(price, currency, country); | |
const priceBeforeDiscount = basePrice !== null ? helpers.formatPrice(basePrice, currency, country) : null; | |
if (salePriceItem) { | |
salePriceItem.innerHTML = `<span data-bigc-price="${priceFinal}" class="klevu-cg-sp-prices">${label} ${priceFinal}</span>`; | |
} | |
if (origPriceItem && parseFloat(price) > parseFloat(salePrice)) { | |
origPriceItem.innerHTML = `<span data-bigc-price="${priceBeforeDiscount}" class="klevu-cg-prices">${priceBeforeDiscount}</span>`; | |
} | |
} | |
} | |
}); | |
} | |
idx++; | |
} | |
klevu.search.base.getScope().template.setHelper('formatPrice', formatPrice); | |
klevu.search.base.getScope().template.setHelper('findProductList', findProductList); | |
klevu.search.base.getScope().template.setHelper('clearElementsById', clearElementsById); | |
klevu.search.base.getScope().template.setHelper('fetchPrices', fetchPrices); | |
klevu.search.base.getScope().template.setHelper('cleanUpProductId', cleanUpProductId); | |
klevu.search.base.getScope().template.setHelper('renderPricesOnFrontend', renderPricesOnFrontend); | |
}); | |
//Below code is for quick search. | |
klevu.afterTemplateRender("quick", function (data, scope) { | |
const helpers = klevu.search.base.getScope().template.getHelpers(); | |
const salePriceSelector = '.klevuQuickSalePrice'; | |
const kuProductSelector = '.kuQuickResultsListContainer .klevuProduct'; | |
const bcCurrentCurrencyCodeForKS = "{{currency_selector.active_currency_code}}"; | |
helpers.clearElementsById(document.querySelectorAll(salePriceSelector)); | |
const klevuResponse = klevu.getObjectPath(data, "response.current.queryResults"); | |
const productList = typeof helpers.findProductList(klevuResponse) !== 'undefined' | |
? (helpers.findProductList(klevuResponse)).records | |
: null; | |
if (!productList) return; | |
const arrayIDs = productList.map(element => element.id); | |
helpers.fetchPrices(arrayIDs, (result) => { | |
helpers.renderPricesOnFrontend( | |
result, | |
productList, | |
salePriceSelector, | |
kuProductSelector, | |
'US', | |
bcCurrentCurrencyCodeForKS | |
); | |
}); | |
}); | |
klevu.afterTemplateRender("full_page", function (data, scope) { | |
const helpers = klevu.search.base.getScope().template.getHelpers(); | |
const salePriceSelector = '.kuSalePrice'; | |
const origPriceSelector = '.kuOrigPrice'; | |
const kuProductSelector = '.klevuProduct'; | |
const bcCurrentCurrencyCodeForKS = "{{currency_selector.active_currency_code}}"; | |
const klevuResponse = klevu.getObjectPath(data, "response.current.queryResults"); | |
const productList = typeof helpers.findProductList(klevuResponse) !== 'undefined' | |
? (helpers.findProductList(klevuResponse)).records | |
: null; | |
if (!productList) return; | |
const arrayIDs = productList.map(element => element.id); | |
//console.log(JSON.stringify(arrayIDs)); | |
helpers.fetchPrices(arrayIDs, (result) => { | |
helpers.renderPricesOnFrontend( | |
result, | |
productList, | |
salePriceSelector, | |
kuProductSelector, | |
'US', //change this | |
bcCurrentCurrencyCodeForKS | |
); | |
}); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Using Script Manager, inject a script.
Link: https://support.bigcommerce.com/s/article/Using-Script-Manager?language=en_US
Placement: Footer
Location: All Pages
Script category: Essential
Script Type: Script
Script Contents: Take content(s) of the price-from-bigcommerce.txt file
Hit Save button