PageSourceSearch

https://us.zwift.com/cdn/shop/t/84/assets/product-recommendations.js?v=127096830375957167321790107217

js zwift.com collected 2026-09-24 08:45:30 UTC 2,668 bytes, 2 lines download raw bytes

1import{Component}from"@theme/component";import{morphSection}from"@theme/section-renderer";class ProductRecommendations extends Component{#intersectionObserver=new IntersectionObserver((entries,observer)=>{entries[0]?.isIntersecting&&(observer.disconnect(),this.#loadRecommendations())},{rootMargin:"0px 0px 400px 0px"});#mutationObserver=new MutationObserver(mutations=>{for(const mutation of mutations)if(!(mutation.target!==this||mutation.type!=="attributes")&&mutation.attributeName!=="data-error"&&!(mutation.attributeName==="class"&&this.classList.contains("hidden"))&&!(mutation.attributeName==="data-recommendations-performed"&&this.dataset.recommendationsPerformed==="true")){this.#loadRecommendations();break}});#cachedRecommendations={};#activeFetch=null;connectedCallback(){super.connectedCallback(),this.#intersectionObserver.observe(this),this.#mutationObserver.observe(this,{attributes:!0})}disconnectedCallback(){super.disconnectedCallback(),this.#intersectionObserver.disconnect(),this.#mutationObserver.disconnect()}#loadRecommendations(){const{productId,recommendationsPerformed,sectionId,intent}=this.dataset;if(!productId||!sectionId)throw new Error("Product ID and a section ID are required");recommendationsPerformed!=="true"&&this.#fetchCachedRecommendations(productId,sectionId,intent).then(result=>{if(!result.success){Shopify.designMode||this.#handleError(new Error(`Server returned ${result.status}`));return}result.data?.trim().length?(this.dataset.recommendationsPerformed="true",morphSection(sectionId,result.data,{mode:"hydration",injectStylesheet:!0})):this.#handleError(new Error("No recommendations available"))}).catch(e=>{this.#handleError(e)})}async#fetchCachedRecommendations(productId,sectionId,intent){const url=`${this.dataset.url}&product_id=${productId}&section_id=${sectionId}&intent=${intent}`,cachedResponse=this.#cachedRecommendations[url];if(cachedResponse)return{success:!0,data:cachedResponse};this.#activeFetch?.abort(),this.#activeFetch=new AbortController;try{const response=await fetch(url,{signal:this.#activeFetch.signal});if(!response.ok)return{success:!1,status:response.status};const text=await response.text();return this.#cachedRecommendations[url]=text,{success:!0,data:text}}finally{this.#activeFetch=null}}#handleError(error){console.error("Product recommendations error:",error.message),this.classList.add("hidden"),this.dataset.error="Error loading product recommendations"}}customElements.get("product-recommendations")||customElements.define("product-recommendations",ProductRecommendations);
2//# sourceMappingURL=/cdn/shop/t/84/assets/product-recommendations.js.map?v=127096830375957167321790107217

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.