### Integrate Fast Simon Scripts (Shopify) Source: https://context7.com/context7/fastsimon_customization/llms.txt Includes Fast Simon JavaScript and CSS for Shopify themes by referencing provided Liquid includes. Ensure these are placed within the section of your theme's main layout file (e.g., theme.liquid). ```html {% include 'fast-simon-js' %} {% include 'fast-simon-css' %} ``` -------------------------------- ### Enable SPA Mode and Callbacks (HTML/JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Configures Fast Simon's Single Page Application (SPA) mode. This script enables client-side navigation, defines which sections should dynamically update, and sets up callback functions to execute before and after navigation events. ```html ``` -------------------------------- ### Setup Custom Filters with Event Listener - JavaScript Source: https://docs.fastsimon.com/customization/docs/plp/examples/create-slider-from-checkboxes-filter This snippet sets up custom filters for Fast Simon search results. It queries filter elements, extracts numerical values, and creates sliders. It also includes event listeners to ensure the setup runs when Fast Simon is ready. ```javascript const filterElement = element.querySelector(`[id="${filterID}"]`); if (filterElement) { const filterValues = Array.from(filterElement.querySelectorAll('.fs-serp-filter-text')).map(el => parseFloat(el.textContent.trim())); if (filterValues.length > 0) { createSlider(filterElement, Math.min(...filterValues), Math.max(...filterValues), filterID.replace('fs_filter_', '')); } } }); }); } // Ensures the filter setup is executed when Fast Simon is ready. if (window.SerpOptions) { setupFilters(); } else { window.addEventListener('fast-serp-ready', setupFilters); } ``` -------------------------------- ### Customize Autocomplete Container Appearance (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Registers a hook to customize the entire autocomplete container. This example sets a maximum height and prepends a custom header. The code ensures the hook is registered only after the FastAutocomplete API is ready. ```javascript function autocompleteHooks() { FastAutocomplete.registerHook('render-autocomplete', ({element}) => { // Customize entire autocomplete container element.style.maxHeight = '600px'; // Add custom header if (!element.querySelector('.custom-header')) { const header = document.createElement('div'); header.className = 'custom-header'; header.innerHTML = '

Search Our Store

'; element.prepend(header); } }); } if (window.FastAutocomplete) { autocompleteHooks(); } else { window.addEventListener('fast-autocomplete-ready', function () { autocompleteHooks(); }); } ``` -------------------------------- ### Product Added to Cart Event Listener - JavaScript Source: https://context7.com/context7/fastsimon_customization/llms.txt Listens for the 'fs-custom-events-product-added-to-cart' event to capture details of products added to the cart. It includes a callback function to log the product data and an example of how to track this event with Google Analytics (gtag). ```javascript function productAddedToCartCallback(productData) { console.log('Product added to cart:', productData); // productData contains: id, title, price, variants, imageURL, etc. // Example: Track with analytics gtag('event', 'add_to_cart', { currency: productData.currency, value: productData.price, items: [{ item_id: productData.id, item_name: productData.title, price: productData.price }] }); } window.addEventListener('fs-custom-events-product-added-to-cart', (e) => { productAddedToCartCallback(e.detail); }); ``` -------------------------------- ### Product Swatch Click and Hover Events Listener - JavaScript Source: https://context7.com/context7/fastsimon_customization/llms.txt Listens for two custom events: 'fs-custom-events-product-swatch-on-hover' to log when a user hovers over a product swatch, and 'fs-custom-events-product-swatch-on-click' to log swatch clicks and track them as a 'select_content' event with Google Analytics (gtag). Both events provide details about the product variant being interacted with. ```javascript // Track swatch hover window.addEventListener('fs-custom-events-product-swatch-on-hover', (e) => { const {alt, image, sku, redirectURL, title, swatchElement, variants} = e.detail; console.log('Hovering over swatch:', title, sku); }); // Track swatch click window.addEventListener('fs-custom-events-product-swatch-on-click', (e) => { const {alt, image, sku, redirectURL, title} = e.detail; console.log('Clicked swatch:', title, sku); gtag('event', 'select_content', { content_type: 'product_variant', content_id: sku }); }); ``` -------------------------------- ### Configure Fast Simon PLP Options (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Sets global configuration options for Fast Simon's Product Listing Page (PLP) using the `__fast_options` object. This allows customization of product attributes, related collections, responsive breakpoints, sorting, column layouts, URL redirects, Shadow DOM rendering, placeholder images, and swatch visibility. ```javascript var __fast_options = __fast_options || {}; // Include product attributes in API responses __fast_options.with_product_attributes = true; // Configure related collections by collection ID __fast_options.relatedCollectionsConfiguration = { 'collectionId1': ['relatedCollectionId1', 'relatedCollectionId2', 'relatedCollectionId3'], 'collectionId2': ['relatedCollectionId4', 'relatedCollectionId5', 'relatedCollectionId6'] }; // Customize responsive breakpoints __fast_options.serp_media_queries = [ {device: 'mobile', query: '(max-width: 480px)'}, {device: 'tablet', query: '(min-width: 481px) and (max-width: 820px)'}, {device: 'desktop', query: '(min-width: 821px)'} ]; // Custom size attribute sorting (lowercase required) __fast_options.variant_size_custom_sort_order = [ 'one size', 'xs', 'small', 'medium', 'large', 'xl', '2x', '3x', '4x', '5x', '6x' ]; // Configure grid columns per device __fast_options.numberOfColumns = { 'desktop': "3", 'tablet': "3", 'mobile': "2" }; // Configure list view columns per device __fast_options.numberOfColumnsList = { 'desktop': "2", 'tablet': "2", 'mobile': "1" }; // Shopify-specific: Include /collections/collectionName in product URLs __fast_options.full_product_url_path_redirect = true; // Disable Shadow DOM rendering __fast_options.disable_shadow_root = false; // Set custom missing product image __fast_options.custom_missing_product_img = "https://cdn.example.com/placeholder.png"; // Hide out-of-stock color swatches __fast_options.hide_oos_swatches = true; // Show carousel navigation dots permanently (not just on hover) __fast_options.show_carousel_marks_not_just_on_hover = true; ``` -------------------------------- ### Integrate Fast Simon Scripts (BigCommerce) Source: https://context7.com/context7/fastsimon_customization/llms.txt Adds Fast Simon JavaScript and CSS to BigCommerce stores by linking to external script and stylesheet URLs. This should be done within the section of your base layout file (e.g., base.html). ```html ``` -------------------------------- ### Product Type Interface (TypeScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Defines the structure for product data, including details like currency, ID, title, price, images, and variant information. This interface is crucial for accessing and manipulating product details within the Fast Simon framework. ```typescript export interface Product { currency: string id: string title: string description: string variants: Variants isSoldOut: boolean price: number comparePrice: number reviewScore: number | undefined reviewCount: number | undefined imageURL: string formattedPrice: string formattedCompare: string | undefined vendor: string sku: string s: string inventory_lvl?: number imagesSrcset: string productURL: string productBadges: Badge[] productTextBadges?: TextBadge[] alternativeProducts?: AlternativeProduct[] tags?: string[] attributes?: Attribute[] } export interface Variants { [variant_id: number]: Record } export type VariantsAttribute = string | number | boolean export interface AlternativeProduct { color: string url: string id: string variants?: Variants s?: string price?: number comparePrice?: number formattedCompare?: string formattedPrice?: string } ``` -------------------------------- ### Quick View Hook - Custom Modal Behavior - JavaScript Source: https://context7.com/context7/fastsimon_customization/llms.txt Registers a 'serp-quick-view' hook to customize the behavior of the quick view modal. This includes logging product details, adding custom buttons to the modal, and programmatically closing the modal after a set delay. It ensures the hook is registered after the Fast Simon library is ready. ```javascript function hooks() { window.SerpOptions.registerHook("serp-quick-view", ({product, index, onClose, mode, element}) => { console.log('Quick view opened:', product.title); console.log('Device mode:', mode); // 'desktop' | 'tablet' | 'mobile' // Add custom button to quick view const customButton = document.createElement('button'); customButton.textContent = 'Custom Action'; customButton.onclick = () => { console.log('Custom action for product:', product.id); }; element.querySelector('.quick-view-content').appendChild(customButton); // Close programmatically after 10 seconds setTimeout(() => { onClose('close-btn', new Event('timeout')); }, 10000); }); } if (window.SerpOptions) { hooks(); } else { window.addEventListener('fast-serp-ready', function () { hooks(); }); } ``` -------------------------------- ### Apply Narrow Filters to Autocomplete Results (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Registers a hook to define filters that narrow down autocomplete suggestions. This example returns filters for 'Tag' (featured, new) and 'Price_from_to' (0-100). It correctly handles the case where FastAutocomplete might not be immediately available. ```javascript function autocompleteHooks() { FastAutocomplete.registerHook('autocomplete-narrow-by', () => { // Return filters to apply to autocomplete results return { "Tag": ["featured", "new"], "Price_from_to": ["0-100"] }; }); } if (window.FastAutocomplete) { autocompleteHooks(); } else { window.addEventListener('fast-autocomplete-ready', function () { autocompleteHooks(); }); } ``` -------------------------------- ### Integrate Fast Simon Scripts (WooCommerce) Source: https://context7.com/context7/fastsimon_customization/llms.txt Embeds Fast Simon JavaScript and CSS into WooCommerce sites via header injection in the 'Insert Header and Footer' plugin. Place the script and link tags in the header section for initialization. ```html ``` -------------------------------- ### Apply Custom Filters with 'send-fast-simon-params' (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Dispatches a 'send-fast-simon-params' event to programmatically apply filters to the product listing. The 'detail' object should contain a 'narrow' property with filter criteria like 'Tag' and 'Price_from_to', using Sets for filter values. ```javascript const chooseTagArray = ['sale', 'new-arrival']; const PriceRange = ['0-50', '50-100']; document.dispatchEvent(new CustomEvent('send-fast-simon-params', { detail: { narrow: { "Tag": new Set(chooseTagArray), "Price_from_to": new Set(PriceRange) } } })); ``` -------------------------------- ### Configure FastSimon Upsell/Cross-sell Options Source: https://context7.com/context7/fastsimon_customization/llms.txt Configures settings for FastSimon's upsell and cross-sell features, specifically enabling or disabling the full-page add-to-cart modal and the Shadow DOM for upsell widgets. These options help customize the user experience for product recommendations and add-to-cart actions. ```javascript var __fast_options = __fast_options || {}; // Open full page add to cart modal __fast_options.upsell_full_page_add_to_cart = true; // Disable Shadow DOM for upsell widgets __fast_options.disable_upsell_shadow_root = false; ``` -------------------------------- ### Handle Add to Cart Response Event (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Listens for the 'fs-custom-events-add-to-cart-response' event to receive cart details after an item is added. It logs the cart information and provides examples for updating the cart item count and total price in the UI. ```javascript window.addEventListener('fs-custom-events-add-to-cart-response', (e) => { const {cart} = e.detail; // cart contains: token, item_count, total_price, items[] console.log('Cart updated:', cart); console.log('Total items:', cart.item_count); console.log('Total price:', cart.total_price); // Update cart UI document.querySelector('.cart-count').textContent = cart.item_count; }); ``` -------------------------------- ### Format Size Variant Selector Options - JavaScript Source: https://context7.com/context7/fastsimon_customization/llms.txt Registers a 'format-serp-size-variant-selector-options' hook to modify how size variant text is displayed. This example abbreviates 'Small', 'Medium', and 'Large' to 'S', 'M', and 'L' respectively. It ensures the hook is registered after the Fast Simon library is ready. ```javascript function hooks() { window.SerpOptions.registerHook("format-serp-size-variant-selector-options", (sizeText) => { // Example: abbreviate size text return sizeText.replace('Small', 'S').replace('Medium', 'M').replace('Large', 'L'); }); } if (window.SerpOptions) { hooks(); } else { window.addEventListener('fast-serp-ready', function () { hooks(); }); } ``` -------------------------------- ### Pagination Change Event Listener - JavaScript Source: https://context7.com/context7/fastsimon_customization/llms.txt Listens for the 'fs-custom-events-pagination-change' event to detect when a user navigates between pages. It logs the previous and current page numbers and provides an example of tracking this interaction as a 'page_view' event with Google Analytics (gtag). ```javascript window.addEventListener('fs-custom-events-pagination-change', (e) => { const {prevPage, currentPage} = e.detail; console.log(`Pagination changed from page ${prevPage} to ${currentPage}`); // Example: Track page view gtag('event', 'page_view', { page_title: `Collection - Page ${currentPage}`, page_location: window.location.href }); }); ``` -------------------------------- ### Add Trending Icon to Popular Search Suggestions (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Registers a hook to modify the rendering of popular search items in the autocomplete. This example prepends a '🔥' icon to each popular search suggestion. It ensures the FastAutocomplete API is ready before registering the hook. ```javascript function autocompleteHooks() { FastAutocomplete.registerHook('render-autocomplete-popular-search-item', ({search, index, element}) => { // Add trending icon to popular searches const trendingIcon = document.createElement('span'); trendingIcon.innerHTML = '🔥'; trendingIcon.className = 'trending-icon'; element.prepend(trendingIcon); }); } if (window.FastAutocomplete) { autocompleteHooks(); } else { window.addEventListener('fast-autocomplete-ready', function () { autocompleteHooks(); }); } ``` -------------------------------- ### Handle Add-to-Cart with Custom DOM Events (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Listen for custom DOM events dispatched by FastSimon for 'quick add' clicks and 'add to cart' responses. This allows you to push relevant e-commerce data to the `dataLayer` for tracking. Ensure `window.dataLayer` is initialized before pushing events. Error handling for add-to-cart failures is also demonstrated. ```javascript window.dataLayer = window.dataLayer || []; // Quick Add button clicked document.addEventListener('fs-custom-events-product-quick-add-clicked', function (evt) { window.dataLayer.push({ event: 'view_quick_add_to_cart', ecommerce: { // Build items from evt.detail if available } }); }); // Add to cart success response document.addEventListener('fs-custom-events-add-to-cart-response', function (evt) { const cartResponse = evt?.detail?.cart; window.dataLayer.push({ event: 'add_to_cart', ecommerce: { // Build items from cartResponse currency: 'USD', value: cartResponse?.total_price || 0, items: cartResponse?.items || [] } }); }); // Optional: listen for add-to-cart error document.addEventListener('fs-custom-events-add-to-cart-error-response', function (evt) { const error = evt?.detail?.res; console.error('Add to cart failed:', error); }); ``` -------------------------------- ### Include FastSimon Scripts and CSS in Shopify Theme Source: https://docs.fastsimon.com/customization/docs/intro This snippet demonstrates how to include FastSimon's JavaScript and CSS files within a Shopify theme's `theme.liquid` file. Ensure the `fast-simon-js` and `fast-simon-css` files are created or uploaded to your theme's snippets directory. ```liquid {% include 'fast-simon-js' %} {% include 'fast-simon-css' %} ``` -------------------------------- ### Custom Color Swatches for Filters and Product Grid - JavaScript Source: https://context7.com/context7/fastsimon_customization/llms.txt This script registers hooks for both 'serp-filters' and 'serp-product-grid' to customize color swatches. It iterates through color swatch elements, sets their background color, and applies a background image using a pattern URL derived from the color name. This allows for visual representation of colors using custom images and ensures compatibility with FastSimon's event system. ```javascript function getProductElements(element) { return [...element.querySelectorAll('.fs-results-product-card')]; } function hooks() { let assetUrl = "https://cdn.shopify.com/s/files/1/0642/9497/7770/files/"; // Apply to filter color swatches window.SerpOptions.registerHook("serp-filters", ({filters, element}) => { if (typeof element !== 'undefined' && element.querySelectorAll('.swatches').length > 0) { var allColorSwatches = element.querySelectorAll(".color-swatch-container.fs-color-swatch-container"); if (allColorSwatches.length > 0) { allColorSwatches.forEach(function (swatchContainer) { let colorName = swatchContainer.querySelector('.color-swatch-color-name').innerHTML.toLowerCase(); let swatch = swatchContainer.querySelector('.color-swatch'); swatch.style.backgroundColor = colorName; colorName = colorName.replaceAll('/', '-') + '_50x50.png'; colorName = colorName.replaceAll(' ', '-'); colorName = colorName.replaceAll('color_', ''); colorName = assetUrl + colorName; if (swatch.style.backgroundColor === '' || swatch.style.backgroundColor !== swatchContainer.querySelector('.color-swatch-color-name').innerHTML.toLowerCase()) { swatch.style.backgroundImage = "url(" + colorName + ")"; } }); } } }); // Apply to product grid color swatches window.SerpOptions.registerHook("serp-product-grid", ({products, element}) => { for (const productElement of getProductElements(element)) { const productID = productElement.dataset.productId; const data = products[productID]; var allColorSwatches = productElement.querySelectorAll(".color-swatch-container"); if (allColorSwatches.length > 0) { allColorSwatches.forEach(function (swatchContainer) { let colorName = swatchContainer.querySelector('.color-swatch-color-name').innerHTML.toLowerCase(); let swatch = swatchContainer.querySelector('.color-swatch'); swatch.style.backgroundColor = colorName; colorName = colorName.replaceAll('/', '-') + '_50x50.png'; colorName = colorName.replaceAll(' ', '-'); colorName = colorName.replaceAll('color_', ''); colorName = assetUrl + colorName; if (swatch.style.backgroundColor === '' || swatch.style.backgroundColor !== swatchContainer.querySelector('.color-swatch-color-name').innerHTML.toLowerCase()) { swatch.style.backgroundImage = "url(" + colorName + ")"; } }); } } }); } if (window.SerpOptions) { hooks(); } else { window.addEventListener('fast-serp-ready', function () { hooks(); }); } ``` -------------------------------- ### Add Custom Labels to PLP Product Grid (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Implements a Product Listing Page (PLP) hook to dynamically add custom promotional labels to product cards based on product tags. It defines helper functions to manage labels and registers a hook with `SerpOptions` to iterate through products and apply labels. The hook ensures compatibility by waiting for `fast-serp-ready` if `SerpOptions` is not immediately available. ```javascript const PROMO_LABELS = { 'Women Sale': 'Sale!!' }; function getProductPromos(tags) { return tags.reduce((promos, tag) => { if (tag in PROMO_LABELS) { promos.push(PROMO_LABELS[tag]); } return promos; }, []); } function getProductElements(element) { return [...element.querySelectorAll('.fs-results-product-card')]; } function removePromo(productElement) { const container = productElement.querySelector(".my-promo-labels"); if (container) { container.remove(); } } function addPromo(productElement, value) { let container = productElement.querySelector(".my-promo-labels"); if (!container) { productElement.querySelector(".info-container").insertAdjacentHTML('afterend', '
'); container = productElement.querySelector(".my-promo-labels"); } container.insertAdjacentHTML("beforeend", ``); } function hooks() { window.SerpOptions.registerHook("serp-product-grid", ({products, element}) => { for (const productElement of getProductElements(element)) { const productID = productElement.dataset.productId; const {tags} = products[productID]; const promos = tags ? getProductPromos(tags) : []; removePromo(productElement); for (const promo of promos) { addPromo(productElement, promo); } } }); } if (window.SerpOptions) { hooks(); } else { window.addEventListener('fast-serp-ready', function () { hooks(); }); } ``` -------------------------------- ### Facet Type Interface (TypeScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Defines the structure for facet data, used for filtering products. It includes facet ID, name, and a list of facet values, each with its own name, display name, and count. ```typescript export type Facet = { id: string name: string values: FacetValue[] meta?: Record } export interface FacetValue { name: string displayName: string count: number meta?: Record } ``` -------------------------------- ### Manage Wishlist with Custom Events (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Handles custom events for checking, adding, and removing products from a wishlist. It uses localStorage for persistence and assumes the existence of helper functions for wishlist operations. This implementation allows for custom logic integration with Fast Simon's wishlist functionality. ```javascript window.addEventListener('fs_wishlist_custom_check', (e) => { const {productID, variantID, callback} = e.detail; // Example: Check against your wishlist system const isInWishlist = checkIfProductInWishlist(productID, variantID); // Return result via callback callback(isInWishlist); }); // Add product to wishlist window.addEventListener('fs_wishlist_custom_add', (e) => { const {productID, variantID, productURL, event, WishlistButtonElement} = e.detail; // Example: Add to your wishlist system addProductToWishlist(productID, variantID, productURL); console.log(`Added product ${productID} to wishlist`); }); // Remove product from wishlist window.addEventListener('fs_wishlist_custom_remove', (e) => { const {productID, variantID, event, WishlistButtonElement} = e.detail; // Example: Remove from your wishlist system removeProductFromWishlist(productID, variantID); console.log(`Removed product ${productID} from wishlist`); }); // Implementation functions function checkIfProductInWishlist(productID, variantID) { const wishlist = JSON.parse(localStorage.getItem('wishlist') || '[]'); return wishlist.some(item => item.productID === productID && item.variantID === variantID); } function addProductToWishlist(productID, variantID, productURL) { const wishlist = JSON.parse(localStorage.getItem('wishlist') || '[]'); wishlist.push({productID, variantID, productURL}); localStorage.setItem('wishlist', JSON.stringify(wishlist)); } function removeProductFromWishlist(productID, variantID) { let wishlist = JSON.parse(localStorage.getItem('wishlist') || '[]'); wishlist = wishlist.filter(item => !(item.productID === productID && item.variantID === variantID)); localStorage.setItem('wishlist', JSON.stringify(wishlist)); } ``` -------------------------------- ### Filter Clicked Event Listener - JavaScript Source: https://context7.com/context7/fastsimon_customization/llms.txt Listens for the 'fs-custom-events-filter-clicked' event to capture when a filter is applied by the user. It logs the filter name and its value, distinguishing between standard filters and price range filters. An example shows how to track this with Google Analytics (gtag) as a 'filter_applied' event. ```javascript window.addEventListener('fs-custom-events-filter-clicked', (e) => { const {filterName, value} = e.detail; if (typeof value === 'object' && 'min' in value) { // Price range filter console.log(`Filter ${filterName}: ${value.min} - ${value.max}`); } else { // Standard filter console.log(`Filter ${filterName}: ${value}`); } // Track with analytics gtag('event', 'filter_applied', { filter_name: filterName, filter_value: JSON.stringify(value) }); }); ``` -------------------------------- ### Configure FastSimon Autocomplete Options Source: https://context7.com/context7/fastsimon_customization/llms.txt Controls settings for the FastSimon autocomplete search, such as the maximum number of products to display per device, inclusion of product attributes and variants, and display of popular searches. It also allows customization of device breakpoints and parsing functions for product titles, prices, and comparison values. ```javascript var __fast_options = __fast_options || {}; // Control maximum displayed products per device __fast_options.max_ac_products_desktop = 5; __fast_options.max_ac_products_tablet = 3; __fast_options.max_ac_products_mobile = 2; // Include product attributes and variants __fast_options.with_product_attributes = true; __fast_options.with_product_variants = true; // Show popular searches when input is empty __fast_options.display_popular_on_empty_term = true; // Show popular searches when no results found __fast_options.display_popular_on_no_results = false; // Customize device breakpoints __fast_options.mobileMedieaQuery = {maxWidth: 600}; __fast_options.tabletMedieaQuery = {minWidth: 600, maxWidth: 999}; __fast_options.desktopMedieaQuery = {minWidth: 1000}; // Enable Single Page Application mode __fast_options.full_spa = true; // Keep autocomplete panel open always __fast_options.forceOpenAlways = false; // Disable Shadow DOM for autocomplete __fast_options.disable_ac_shadow_root = false; // Custom parsers for display formatting __fast_options.parseAcProductTitle = (title) => { return title.replaceAll(" ", ","); }; __fast_options.parseAcProductPrice = (price) => { return "$" + price; }; __fast_options.parseAcProductCompare = (compare) => { return "$" + compare; }; ``` -------------------------------- ### Customize GA4 Events with Callbacks (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Disable default GA4 events like 'view_item_list', 'select_item', 'select_promotion', and 'add_to_cart' and provide custom callbacks to push data to the dataLayer. This allows for tailored event tracking based on specific user interactions and business logic. Ensure the `window.dataLayer` object is initialized. ```javascript window.__fast_options = window.__fast_options || {}; // A) Disable default "view_item_list" and handle yourself __fast_options.avoidDefaultViewItemListEvent = true; __fast_options.viewItemListCallback = function (payload) { // payload: { items: [...], promotions?: [...], category?: 'filter' } if (payload && Array.isArray(payload.items) && payload.items.length) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'select_item', ecommerce: { items: payload.items } }); } // Handle promotions if present if (payload && Array.isArray(payload.promotions) && payload.promotions.length) { window.dataLayer.push({ event: 'view_promotion', ecommerce: { items: payload.promotions } }); } }; // B) Disable default "select_item" (product click) and emit your own event __fast_options.avoidDefaultSelectItemEvent = true; __fast_options.selectItemCallback = function (payload) { // payload: { items: [...] } if (payload && Array.isArray(payload.items) && payload.items.length) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'select_item', ecommerce: { items: payload.items } }); } }; // C) Disable default "select_promotion" and emit your own event __fast_options.avoidDefaultSelectPromotionEvent = true; __fast_options.selectPromotionCallback = function (payload) { // payload: { items: [...] } if (payload && Array.isArray(payload.items) && payload.items.length) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'select_promotion', ecommerce: { items: payload.items } }); } }; // D) Disable default "add_to_cart" and emit your own event __fast_options.avoidDefaultAddToCartEvent = true; __fast_options.addToCartCallback = function (payload) { // payload: { items: [...] } if (payload && Array.isArray(payload.items) && payload.items.length) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'add_to_cart', ecommerce: { items: payload.items } }); } }; ``` -------------------------------- ### Custom Autocomplete Styling (CSS) Source: https://context7.com/context7/fastsimon_customization/llms.txt Applies custom CSS to the Fast Simon autocomplete component. This style block customizes the main container, individual product items, product titles, prices, and custom badges, ensuring a unique look and feel. ```css /* Autocomplete container */ .fast-autocomplete-container { border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.1); max-width: 600px; } /* Product suggestions */ .autocomplete-product-item { padding: 12px; border-bottom: 1px solid #eee; transition: background 0.2s; } .autocomplete-product-item:hover { background: #f5f5f5; } /* Product title */ .product-title { font-weight: 600; color: #333; font-size: 14px; } /* Product price */ .product-price { color: #666; font-size: 13px; } /* Custom badge */ .custom-badge { background: #4CAF50; color: white; padding: 2px 6px; border-radius: 3px; font-size: 10px; margin-left: 8px; } ``` -------------------------------- ### Round Prices with JavaScript Source: https://docs.fastsimon.com/customization/docs/plp/examples/round-prices This script rounds product prices to the nearest whole number and formats them to two decimal places. It hooks into the FastSimon Search Results Page (SERP) product grid to modify the displayed price. Ensure the FastSimon library is loaded before this script executes. ```javascript ``` -------------------------------- ### Custom Product Listing Page (PLP) Styling (CSS) Source: https://context7.com/context7/fastsimon_customization/llms.txt Applies custom CSS to the Product Listing Page (PLP) within Fast Simon widgets. This style block targets product cards, promo labels, filter containers, and color swatches, ensuring compatibility with Shadow DOM. ```css /* Custom product card styling */ .fs-results-product-card { border: 2px solid #e0e0e0; border-radius: 8px; transition: transform 0.2s; } .fs-results-product-card:hover { transform: translateY(-4px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); } /* Custom label styling */ .my-promo-labels { position: absolute; top: 10px; right: 10px; background: #ff0000; color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold; font-size: 12px; } /* Filter styling */ .fs-filter-container { background: #f9f9f9; padding: 16px; border-radius: 8px; } /* Color swatch styling */ .color-swatch { border: 2px solid #ddd; border-radius: 50%; width: 32px; height: 32px; background-size: cover; background-position: center; } .color-swatch:hover { border-color: #000; } ``` -------------------------------- ### Implement Fixed Narrow Filter with FastSimon JS Source: https://docs.fastsimon.com/customization/docs/plp/examples/fixed-narrow This JavaScript code adds a fixed narrow filter to the page if the URL includes 'shirt'. It registers a hook with `window.SerpOptions` to apply filters for 'Shirt' type, 'sale' tag, and a price range of 0-100. The hook is executed when `window.SerpOptions` is available or after the 'fast-serp-ready' event. ```javascript function hooks() { if(window.location.href.includes("shirt")){ window.SerpOptions.registerHook("serp-fixed-narrow", () => ({"Type": ["Shirt"],"Tag": ["sale"],"Price_from_to":["0-100"]})); } } // execution here if (window.SerpOptions) { hooks(); } else { window.addEventListener('fast-serp-ready', function () { hooks(); }); } ``` -------------------------------- ### Add Discount Percentage Label to Product Grid - JavaScript Source: https://context7.com/context7/fastsimon_customization/llms.txt This script registers a hook for the 'serp-product-grid' event to add a discount percentage label to products. It calculates the save percentage based on the product's price and compare price, and appends a 'Save X%' label if a discount is applicable. It ensures labels are not duplicated and handles cases where FastSimon's API might not be immediately ready. ```javascript function getProductElements(element) { return [...element.querySelectorAll('.fs-results-product-card')]; } function removeLabel(productElement) { const label = productElement.querySelector(".my-promo-label"); if (label) { label.remove(); } } function addLabel(productElement, data) { const save = Math.round((data.comparePrice - data.price) * 100 / data.comparePrice); if (productElement.querySelectorAll('.my-promo-labels').length === 0) { productElement.querySelector(".info-container").insertAdjacentHTML('beforeend', `
Save ${save}%
`); } } function hooks() { window.SerpOptions.registerHook("serp-product-grid", ({products, element}) => { for (const productElement of getProductElements(element)) { const productID = productElement.dataset.productId; const data = products[productID]; removeLabel(productElement); if (parseFloat(data.comparePrice) > 0 && parseFloat(data.comparePrice) > parseFloat(data.price)) { addLabel(productElement, data); } } }); } if (window.SerpOptions) { hooks(); } else { window.addEventListener('fast-serp-ready', function () { hooks(); }); } ``` -------------------------------- ### Customize Autocomplete Product Item Rendering (JavaScript) Source: https://context7.com/context7/fastsimon_customization/llms.txt Register a hook for the 'render-autocomplete-product-item' lifecycle event in FastAutocomplete to customize how product suggestions are displayed. This hook receives product details and the DOM element, allowing you to modify the product title, add custom badges, or inject other elements. The hook is registered only if `FastAutocomplete` is available or after the 'fast-autocomplete-ready' event. ```javascript function autocompleteHooks() { FastAutocomplete.registerHook('render-autocomplete-product-item', ({product, index, element}) => { // product contains: id, title, price, imageURL, etc. // Add custom badge to product if (product.price < 20) { const badge = document.createElement('span'); badge.className = 'custom-badge'; badge.textContent = 'Budget-Friendly'; element.querySelector('.product-info').appendChild(badge); } // Modify product title display const titleElement = element.querySelector('.product-title'); if (titleElement) { titleElement.textContent = `#${index + 1} - ${product.title}`; } }); } if (window.FastAutocomplete) { autocompleteHooks(); } else { window.addEventListener('fast-autocomplete-ready', function () { autocompleteHooks(); }); } ``` -------------------------------- ### Add Custom CSS via Global Style Element Source: https://docs.fastsimon.com/customization/docs/autocomplete/styling This snippet demonstrates how to add custom CSS for the Fast Simon Autocomplete by using a global ` ``` -------------------------------- ### Update Product Prices from Shopify JSON using JavaScript Source: https://docs.fastsimon.com/customization/docs/plp/examples/get-price-from-json-shopify This script fetches product data from Shopify's JSON endpoint and dynamically updates the displayed price and compare-at-price for products. It handles cases where compare-at-price is not available and appends a '+ gst' indicator if necessary. This function is designed to be used within FastSimon's event hooks for product grids and autocomplete. ```javascript function getProductElements(element) { return [...element.querySelectorAll(`.fs-results-product-card`)]; } function setNewPrice(productElement, newPrice, newCompare, country) { let priceElement = productElement.querySelector('.price, .fs-price'); let compareElement = null; if(newCompare) { compareElement = productElement.querySelector('.compare, .fs-price.compare'); } if(newPrice && priceElement) { if(compareElement) { priceElement.textContent = "$" + newPrice; } else { priceElement.textContent = "$" + newPrice; if (priceElement.querySelectorAll(`.tax-title`).length === 0) { priceElement.insertAdjacentHTML('beforeend', '+ gst'); } } } if(newCompare) { if(compareElement) { compareElement.textContent = "$" + newCompare; if (compareElement.querySelectorAll(`.tax-title`).length === 0) { compareElement.insertAdjacentHTML('beforeend', '+ gst'); } } } } async function setProductSpecialPrice(productElement, pId, productURL){ const country = Shopify?.country; if(!productURL) { return; } const splattedURL = productURL.split('?'); let fullURL = `${splattedURL[0]}.json${splattedURL?.[1] ? `?${splattedURL[1]}` : ''}`; const res = await fetch(fullURL); const data = await res.json(); const product = data.product; const variantID = productURL.split('&').find(param => param.includes('variant'))?.split('=')?.[1]; const variant = product.variants.find((variant) => variant.id === Number(variantID)) || product.variants?.[0]; if (variant) { const compare = variant?.compare_at_price ? variant?.compare_at_price : undefined; const price = variant?.price ? variant?.price : 0; setNewPrice(productElement, price, compare, country); } } function hooks() { console.log("country - " + Shopify?.country); SerpOptions.registerHook('serp-product-grid', ({products, element}) => { for (const productElement of getProductElements(element)) { /* get product data */ const productID = productElement.dataset.productId; const data = products[productID]; if ( typeof(data) !== "undefined" && data !== null ) { let productURL = data.productURL || ''; setProductSpecialPrice(productElement, productID, productURL); } } }); } function AChooks() { FastAutocomplete.registerHook('render-autocomplete-product-item', ({product, index, element}) => { //Set up special prices let productURL = product.u || ''; let productID = product.id; setProductSpecialPrice(element, productID, productURL); }); } if (window.FastAutocomplete) { AChooks(); } else { window.addEventListener('fast-autocomplete-ready', function () { AChooks(); }); } // execution here if (window.SerpOptions) { hooks(); } else { window.addEventListener('fast-serp-ready', function () { hooks(); }); } //end for Vnext ```