From a6dd4ab1e9555c1db3341d57cf10cb068470e284 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:44:29 +0000 Subject: [PATCH 1/6] Initial plan From 4a191c80987a2d6f8d8b72d1663b13b14b5c8b88 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:48:47 +0000 Subject: [PATCH 2/6] Add fallback mechanism documentation for search and category merchandising Co-authored-by: timowestnosto <13622115+timowestnosto@users.noreply.github.com> --- .../implementing-category-pages.md | 62 +++++++++++ .../implement-search/search/README.md | 100 ++++++++++++++++++ 2 files changed, 162 insertions(+) diff --git a/implementing-nosto/implement-search/implement-search-using-api/implementing-category-pages.md b/implementing-nosto/implement-search/implement-search-using-api/implementing-category-pages.md index a991058..a5d18fa 100644 --- a/implementing-nosto/implement-search/implement-search-using-api/implementing-category-pages.md +++ b/implementing-nosto/implement-search/implement-search-using-api/implementing-category-pages.md @@ -132,3 +132,65 @@ To analyze user behavior you need to implement tracking. This can be achieved us * [recordSearch](../search/#search-1) to track category page visits * [recordSearchClick](../search/#search-product-keyword-click) to track clicks on category results +## Fallback mechanism + +Similar to search implementations, category merchandising via API requires fallback mechanisms to handle errors and timeouts gracefully. + +### Implementation guidance + +When the category API call returns an error or takes longer than 1 second to respond, the integration should fall back to the native category page solution: + +```javascript +async function loadCategoryWithFallback(categoryId, categoryPath) { + const timeout = 1000; // 1 second timeout + + try { + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error('Category API timeout')), timeout); + }); + + const categoryPromise = fetch(`https://search.nosto.com/v1/graphql`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${YOUR_TOKEN}` + }, + body: JSON.stringify({ + query: ` + query { + search( + accountId: "${YOUR_ACCOUNT_ID}" + products: { + categoryId: "${categoryId}", + categoryPath: "${categoryPath}" + } + ) { + products { + hits { + productId + name + url + imageUrl + price + } + total + } + } + } + ` + }) + }).then(response => response.json()); + + const result = await Promise.race([categoryPromise, timeoutPromise]); + return result; + + } catch (error) { + console.warn('Nosto category API failed, using native category logic:', error); + // Fallback to native category page implementation + return await loadNativeCategoryProducts(categoryId, categoryPath); + } +} +``` + +This ensures users always see category products, even when the Nosto API is unavailable or slow to respond. + diff --git a/implementing-nosto/implement-search/search/README.md b/implementing-nosto/implement-search/search/README.md index 4865834..093376f 100644 --- a/implementing-nosto/implement-search/search/README.md +++ b/implementing-nosto/implement-search/search/README.md @@ -388,4 +388,104 @@ Tracking product clicks is fundamental for understanding user interaction. Use ` In case of an SPA based integration the `api.recordSearchClick` calls should be complemented with Session API or `api.createRecommendationRequest()` usage to couple the search analytics events to generic Nosto events for accurate attribution. +## Fallback mechanism + +For JS API integrations, there is no built-in fallback functionality. Merchants need to build this themselves to ensure a robust search experience. + +### When to implement fallbacks + +You should implement fallback mechanisms in the following scenarios: + +* **Search query errors**: When the search API returns an error response +* **Timeout scenarios**: When the search query takes longer than 1 second to return results +* **Network connectivity issues**: When there are network problems preventing API calls + +### Recommended fallback approach + +When implementing fallback functionality, consider the following approach: + +```javascript +async function searchWithFallback(query, options = {}) { + const timeout = options.timeout || 1000; // Default 1 second timeout + + try { + // Set up timeout promise + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error('Search timeout')), timeout); + }); + + // Race between search and timeout + const searchPromise = new Promise((resolve, reject) => { + nostojs(api => { + api.search({ + query: query, + products: { + fields: ['name', 'url', 'price'], + size: options.size || 10 + } + }, { + track: 'serp' + }).then(resolve).catch(reject); + }); + }); + + const response = await Promise.race([searchPromise, timeoutPromise]); + return response; + + } catch (error) { + console.warn('Nosto search failed, falling back to native search:', error); + // Fallback to your native search solution + return await executeNativeSearch(query, options); + } +} + +async function executeNativeSearch(query, options) { + // Implement your native search fallback here + // This could redirect to your default search page or use an alternative search service + window.location.href = `/search?q=${encodeURIComponent(query)}`; +} +``` + +### Implementation considerations + +* **Error handling**: Always wrap Nosto search calls in try-catch blocks +* **Timeout management**: Implement reasonable timeout values (recommended: 1 second) +* **User experience**: Ensure seamless transition to fallback without visible errors +* **Analytics**: Track fallback usage to monitor search performance + +### Category merchandising fallbacks + +The same fallback principles apply to category merchandising implementations. When using the search API for category pages, implement similar timeout and error handling: + +```javascript +async function getCategoryProductsWithFallback(categoryId, options = {}) { + try { + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error('Category search timeout')), 1000); + }); + + const categoryPromise = new Promise((resolve, reject) => { + nostojs(api => { + api.search({ + products: { + categoryId: categoryId, + fields: ['name', 'url', 'price'], + size: options.size || 24 + } + }, { + track: 'category' + }).then(resolve).catch(reject); + }); + }); + + return await Promise.race([categoryPromise, timeoutPromise]); + + } catch (error) { + console.warn('Nosto category search failed, falling back:', error); + // Fallback to native category page logic + return await executeNativeCategoryFallback(categoryId, options); + } +} +``` + *** From 05c91c803fdb9ee4a056fb2fe989518a75451b86 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Oct 2025 09:56:34 +0000 Subject: [PATCH 3/6] Remove fallback documentation as requested in review Co-authored-by: timowestnosto <13622115+timowestnosto@users.noreply.github.com> --- .../implementing-category-pages.md | 62 ----------- .../implement-search/search/README.md | 100 ------------------ 2 files changed, 162 deletions(-) diff --git a/implementing-nosto/implement-search/implement-search-using-api/implementing-category-pages.md b/implementing-nosto/implement-search/implement-search-using-api/implementing-category-pages.md index a5d18fa..a991058 100644 --- a/implementing-nosto/implement-search/implement-search-using-api/implementing-category-pages.md +++ b/implementing-nosto/implement-search/implement-search-using-api/implementing-category-pages.md @@ -132,65 +132,3 @@ To analyze user behavior you need to implement tracking. This can be achieved us * [recordSearch](../search/#search-1) to track category page visits * [recordSearchClick](../search/#search-product-keyword-click) to track clicks on category results -## Fallback mechanism - -Similar to search implementations, category merchandising via API requires fallback mechanisms to handle errors and timeouts gracefully. - -### Implementation guidance - -When the category API call returns an error or takes longer than 1 second to respond, the integration should fall back to the native category page solution: - -```javascript -async function loadCategoryWithFallback(categoryId, categoryPath) { - const timeout = 1000; // 1 second timeout - - try { - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => reject(new Error('Category API timeout')), timeout); - }); - - const categoryPromise = fetch(`https://search.nosto.com/v1/graphql`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${YOUR_TOKEN}` - }, - body: JSON.stringify({ - query: ` - query { - search( - accountId: "${YOUR_ACCOUNT_ID}" - products: { - categoryId: "${categoryId}", - categoryPath: "${categoryPath}" - } - ) { - products { - hits { - productId - name - url - imageUrl - price - } - total - } - } - } - ` - }) - }).then(response => response.json()); - - const result = await Promise.race([categoryPromise, timeoutPromise]); - return result; - - } catch (error) { - console.warn('Nosto category API failed, using native category logic:', error); - // Fallback to native category page implementation - return await loadNativeCategoryProducts(categoryId, categoryPath); - } -} -``` - -This ensures users always see category products, even when the Nosto API is unavailable or slow to respond. - diff --git a/implementing-nosto/implement-search/search/README.md b/implementing-nosto/implement-search/search/README.md index 093376f..4865834 100644 --- a/implementing-nosto/implement-search/search/README.md +++ b/implementing-nosto/implement-search/search/README.md @@ -388,104 +388,4 @@ Tracking product clicks is fundamental for understanding user interaction. Use ` In case of an SPA based integration the `api.recordSearchClick` calls should be complemented with Session API or `api.createRecommendationRequest()` usage to couple the search analytics events to generic Nosto events for accurate attribution. -## Fallback mechanism - -For JS API integrations, there is no built-in fallback functionality. Merchants need to build this themselves to ensure a robust search experience. - -### When to implement fallbacks - -You should implement fallback mechanisms in the following scenarios: - -* **Search query errors**: When the search API returns an error response -* **Timeout scenarios**: When the search query takes longer than 1 second to return results -* **Network connectivity issues**: When there are network problems preventing API calls - -### Recommended fallback approach - -When implementing fallback functionality, consider the following approach: - -```javascript -async function searchWithFallback(query, options = {}) { - const timeout = options.timeout || 1000; // Default 1 second timeout - - try { - // Set up timeout promise - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => reject(new Error('Search timeout')), timeout); - }); - - // Race between search and timeout - const searchPromise = new Promise((resolve, reject) => { - nostojs(api => { - api.search({ - query: query, - products: { - fields: ['name', 'url', 'price'], - size: options.size || 10 - } - }, { - track: 'serp' - }).then(resolve).catch(reject); - }); - }); - - const response = await Promise.race([searchPromise, timeoutPromise]); - return response; - - } catch (error) { - console.warn('Nosto search failed, falling back to native search:', error); - // Fallback to your native search solution - return await executeNativeSearch(query, options); - } -} - -async function executeNativeSearch(query, options) { - // Implement your native search fallback here - // This could redirect to your default search page or use an alternative search service - window.location.href = `/search?q=${encodeURIComponent(query)}`; -} -``` - -### Implementation considerations - -* **Error handling**: Always wrap Nosto search calls in try-catch blocks -* **Timeout management**: Implement reasonable timeout values (recommended: 1 second) -* **User experience**: Ensure seamless transition to fallback without visible errors -* **Analytics**: Track fallback usage to monitor search performance - -### Category merchandising fallbacks - -The same fallback principles apply to category merchandising implementations. When using the search API for category pages, implement similar timeout and error handling: - -```javascript -async function getCategoryProductsWithFallback(categoryId, options = {}) { - try { - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => reject(new Error('Category search timeout')), 1000); - }); - - const categoryPromise = new Promise((resolve, reject) => { - nostojs(api => { - api.search({ - products: { - categoryId: categoryId, - fields: ['name', 'url', 'price'], - size: options.size || 24 - } - }, { - track: 'category' - }).then(resolve).catch(reject); - }); - }); - - return await Promise.race([categoryPromise, timeoutPromise]); - - } catch (error) { - console.warn('Nosto category search failed, falling back:', error); - // Fallback to native category page logic - return await executeNativeCategoryFallback(categoryId, options); - } -} -``` - *** From 96a092f52c97a3bc3f7ae850c05b38b012853a57 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Oct 2025 10:07:48 +0000 Subject: [PATCH 4/6] Remove only the "Recommended fallback approach" subsection as requested Co-authored-by: timowestnosto <13622115+timowestnosto@users.noreply.github.com> --- .../implement-search/search/README.md | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/implementing-nosto/implement-search/search/README.md b/implementing-nosto/implement-search/search/README.md index 4865834..373cde6 100644 --- a/implementing-nosto/implement-search/search/README.md +++ b/implementing-nosto/implement-search/search/README.md @@ -388,4 +388,58 @@ Tracking product clicks is fundamental for understanding user interaction. Use ` In case of an SPA based integration the `api.recordSearchClick` calls should be complemented with Session API or `api.createRecommendationRequest()` usage to couple the search analytics events to generic Nosto events for accurate attribution. +## Fallback mechanism + +For JS API integrations, there is no built-in fallback functionality. Merchants need to build this themselves to ensure a robust search experience. + +### When to implement fallbacks + +You should implement fallback mechanisms in the following scenarios: + +* **Search query errors**: When the search API returns an error response +* **Timeout scenarios**: When the search query takes longer than 1 second to return results +* **Network connectivity issues**: When there are network problems preventing API calls + +### Implementation considerations + +* **Error handling**: Always wrap Nosto search calls in try-catch blocks +* **Timeout management**: Implement reasonable timeout values (recommended: 1 second) +* **User experience**: Ensure seamless transition to fallback without visible errors +* **Analytics**: Track fallback usage to monitor search performance + +### Category merchandising fallbacks + +The same fallback principles apply to category merchandising implementations. When using the search API for category pages, implement similar timeout and error handling: + +```javascript +async function getCategoryProductsWithFallback(categoryId, options = {}) { + try { + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error('Category search timeout')), 1000); + }); + + const categoryPromise = new Promise((resolve, reject) => { + nostojs(api => { + api.search({ + products: { + categoryId: categoryId, + fields: ['name', 'url', 'price'], + size: options.size || 24 + } + }, { + track: 'category' + }).then(resolve).catch(reject); + }); + }); + + return await Promise.race([categoryPromise, timeoutPromise]); + + } catch (error) { + console.warn('Nosto category search failed, falling back:', error); + // Fallback to native category page logic + return await executeNativeCategoryFallback(categoryId, options); + } +} +``` + *** From 07f80c7b853bc6f4be4e93bdc96b415037822733 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Oct 2025 13:40:24 +0000 Subject: [PATCH 5/6] Remove Category merchandising fallbacks section and code snippet Co-authored-by: timowestnosto <13622115+timowestnosto@users.noreply.github.com> --- .../implement-search/search/README.md | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/implementing-nosto/implement-search/search/README.md b/implementing-nosto/implement-search/search/README.md index 373cde6..430e4da 100644 --- a/implementing-nosto/implement-search/search/README.md +++ b/implementing-nosto/implement-search/search/README.md @@ -407,39 +407,4 @@ You should implement fallback mechanisms in the following scenarios: * **User experience**: Ensure seamless transition to fallback without visible errors * **Analytics**: Track fallback usage to monitor search performance -### Category merchandising fallbacks - -The same fallback principles apply to category merchandising implementations. When using the search API for category pages, implement similar timeout and error handling: - -```javascript -async function getCategoryProductsWithFallback(categoryId, options = {}) { - try { - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => reject(new Error('Category search timeout')), 1000); - }); - - const categoryPromise = new Promise((resolve, reject) => { - nostojs(api => { - api.search({ - products: { - categoryId: categoryId, - fields: ['name', 'url', 'price'], - size: options.size || 24 - } - }, { - track: 'category' - }).then(resolve).catch(reject); - }); - }); - - return await Promise.race([categoryPromise, timeoutPromise]); - - } catch (error) { - console.warn('Nosto category search failed, falling back:', error); - // Fallback to native category page logic - return await executeNativeCategoryFallback(categoryId, options); - } -} -``` - *** From 2f44a2a7b0789f689a3e601770cb666013ee8ee3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Oct 2025 16:50:09 +0000 Subject: [PATCH 6/6] Update timeout information and remove timeout management line Co-authored-by: timowestnosto <13622115+timowestnosto@users.noreply.github.com> --- implementing-nosto/implement-search/search/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/implementing-nosto/implement-search/search/README.md b/implementing-nosto/implement-search/search/README.md index 430e4da..0d9156b 100644 --- a/implementing-nosto/implement-search/search/README.md +++ b/implementing-nosto/implement-search/search/README.md @@ -397,13 +397,12 @@ For JS API integrations, there is no built-in fallback functionality. Merchants You should implement fallback mechanisms in the following scenarios: * **Search query errors**: When the search API returns an error response -* **Timeout scenarios**: When the search query takes longer than 1 second to return results +* **Timeout scenarios**: JS API based Search requests timeout after 5 seconds, so implement fallbacks for cases when requests take longer than expected * **Network connectivity issues**: When there are network problems preventing API calls ### Implementation considerations * **Error handling**: Always wrap Nosto search calls in try-catch blocks -* **Timeout management**: Implement reasonable timeout values (recommended: 1 second) * **User experience**: Ensure seamless transition to fallback without visible errors * **Analytics**: Track fallback usage to monitor search performance