diff --git a/CHANGELOG.md b/CHANGELOG.md index 0293566..c0c6f12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Fixed +- Fixed formatting for the gtinValue coming back from getAppSettings, if this value is itemId it should not format + ## [0.16.0] - 2025-07-18 ## [0.15.0] - 2025-04-28 diff --git a/react/Product.js b/react/Product.js index b5415e5..eba2a98 100644 --- a/react/Product.js +++ b/react/Product.js @@ -60,16 +60,21 @@ const OUT_OF_STOCK = 'http://schema.org/OutOfStock' const getSKUAvailabilityString = (seller) => isSkuAvailable(seller) ? IN_STOCK : OUT_OF_STOCK -const formatGTIN = (gtin) => { - if (!gtin || typeof gtin !== 'string') return null +const normalizeGTIN = (raw) => { + if (raw === null || raw === undefined) return null + const digits = String(raw).replace(/\D+/g, '') + + if (!digits || /^0+$/.test(digits)) return null const validLengths = [8, 12, 13, 14] - if (validLengths.includes(gtin.length)) return gtin + if (validLengths.includes(digits.length)) return digits + + const validLengthsTarget = validLengths.find((len) => digits.length < len) - const targetLength = validLengths.find((len) => gtin.length < len) || 14 + if (validLengthsTarget) return digits.padStart(validLengthsTarget, '0') - return gtin.padStart(targetLength, '0') + return null } const parseSKUToOffer = ( @@ -82,14 +87,8 @@ const parseSKUToOffer = ( : lowHighForSellers(item.sellers, { pricesWithTax }).low const availability = getSKUAvailabilityString(seller) - const price = getFinalPrice(seller, getSpotPrice, { decimals, pricesWithTax }) - const rawGTIN = item?.[gtinValue] - const isGTINField = gtinValue !== 'itemId' && typeof rawGTIN === 'string' - const gtin = isGTINField ? formatGTIN(rawGTIN) : null - const skuValue = isGTINField ? gtin : item.itemId - // When a product is not available the API can't define its price and returns zero. // If we set structured data product price as zero, Google will show that the // product it's free (wrong info), but out of stock. @@ -98,12 +97,16 @@ const parseSKUToOffer = ( return null } + const rawSkuValue = item?.[gtinValue] + const normalizedGtin = normalizeGTIN(rawSkuValue) + const offerSku = normalizedGtin || item.itemId + const offer = { '@type': 'Offer', price, priceCurrency: currency, availability, - sku: skuValue, + sku: offerSku, itemCondition: 'http://schema.org/NewCondition', priceValidUntil: path(['commertialOffer', 'PriceValidUntil'], seller), seller: { @@ -220,12 +223,12 @@ export const parseToJsonLD = ({ } const baseUrl = getBaseUrl() - const category = getCategoryName(product) const rawGTIN = selectedItem?.[gtinValue] - const gtin = formatGTIN(rawGTIN) - const fallbackSKU = selectedItem?.itemId || null + const gtin = normalizeGTIN(rawGTIN) + + const merchantSKU = gtin || selectedItem?.itemId || null const productLD = { '@context': 'https://schema.org/', @@ -238,7 +241,7 @@ export const parseToJsonLD = ({ : images[0]?.imageUrl || null, description: product.metaTagDescription || product.description, mpn, - sku: gtin || fallbackSKU, + sku: merchantSKU, category, offers: disableOffers ? null : offers, gtin, @@ -275,6 +278,8 @@ function StructuredData({ product, selectedItem }) { gtinValue, }) + if (!productLD) return null + return