Similar Tasting Products Configuration

Table of Contents


Product Cards

Custom Product Card Rendering

Option: renderProductCards
Type: Function
Default: null

Description:
This function gives you complete control over how product cards are rendered in the STP widget. Instead of using the default Preferabli card design, you can fetch and display your own custom HTML templates that match your site's design system. This is particularly useful when integrating with e-commerce platforms like Shopify, WooCommerce, or BigCommerce that have their own product card formats.

The function receives an array of product lookup objects and must return a Promise that resolves to an array of HTML strings. Each HTML string represents one product card.

Example (Shopify):

$(%DIV_ELEMENT%).preferabliSTP({
    renderProductCards: (lookups) => {
        // Filter out products without a landing URL
        const valid = lookups.filter(l => l.landing_url);
        
        // Fetch custom card HTML for each product
        return Promise.all(
            valid.map(l =>
                fetch(`${l.landing_url}?view=stp`)
                    .then(r => {
                        if (!r.ok) throw new Error(`Failed to load ${r.url}: ${r.status}`);
                        return r.text();
                    })
                    .then(html => `${html}`)
                    .catch(err => {
                        console.warn(`Failed to load ${l.landing_url}:`, err);
                        return null;
                    })
            )
        ).then(results => results.filter(Boolean)); // Remove failed requests
    }
});

Product Cards Container

Option: productCardsContainer
Type: Object
Default: null

Description:
Customize the HTML container element that wraps all product cards. This allows the STP widget to integrate seamlessly with your existing CSS framework or e-commerce platform. For example, WooCommerce typically uses <ul class="products"> to contain product listings, so you can configure the container to match this structure.

Without this option, the STP widget uses its default container structure, which may not inherit your site's existing product grid styles.

Properties:

  • element - The HTML tag name for the container (e.g., 'ul', 'div', 'section')
  • class - CSS class name(s) to apply to the container
  • id - Unique identifier for the container element

Example:

$(%DIV_ELEMENT%).preferabliSTP({
    productCardsContainer: {
        element: 'ul',           // Uses <ul> instead of default <div>
        class: 'products',       // Matches WooCommerce class
        id: 'stp-container'      // Custom ID for targeting
    }
});

Important: Ensure these match your existing ecommerce system display


Render Complete Callback

Option: onRenderComplete
Type: Function
Default: null
Required when: renderProductCards is used

Description:
This callback function executes immediately after the STP widget finishes rendering all product cards. It's useful for initializing third-party libraries, triggering analytics events, lazy-loading images, or any other post-render operations.

The function is called with no arguments and should not return a value. Any code inside this function will run after the DOM has been updated with the product recommendations.

Example:

$(%DIV_ELEMENT%).preferabliSTP({
    renderProductCards: (lookups) => {
        // Filter out products without a landing URL
        const valid = lookups.filter(l => l.landing_url);
        
        // Fetch custom card HTML for each product
        return Promise.all(
            valid.map(l =>
                fetch(`${l.landing_url}?view=stp`)
                    .then(r => {
                        if (!r.ok) throw new Error(`Failed to load ${r.url}: ${r.status}`);
                        return r.text();
                    })
                    .then(html => `${html}`)
                    .catch(err => {
                        console.warn(`Failed to load ${l.landing_url}:`, err);
                        return null;
                    })
            )
        ).then(results => results.filter(Boolean)); // Remove failed requests
    },
    onRenderComplete: function() {
        // Initialize a additional functionality
    }
});

Display Options

Developer Mode

Option: devMode
Type: Boolean
Default: false

Description:
Developer mode allows you to test and style the STP widget on a live website without showing it to visitors. When enabled, the widget loads and renders normally but is hidden using CSS (display: none). This is invaluable for front-end developers who need to work on styling and layout in a production environment without affecting the user experience.

You can reveal the hidden widget using your browser's developer tools by removing or disabling the display: none style on the .stp__container element.

How to use:

  1. Enable devMode: true in your configuration
  2. Load the page in your browser
  3. Open Developer Tools (F12 or right-click → Inspect)
  4. Find the .stp__container element
  5. Disable or remove the display: none style
  6. The widget will become visible for styling and testing

Example:

$(%DIV_ELEMENT%).preferabliSTP({
    devMode: true  // Widget loads but remains hidden
});

Open Links in New Tab

Option: openNewTab
Type: Boolean
Default: false

Description:
Controls whether product links open in a new browser tab (or window) when clicked. When enabled, clicking a product card will keep the current page open while opening the product details page in a new tab. This is useful for keeping users engaged with your recommendation flow while allowing them to browse multiple products.

This setting only affects the default product cards. If you're using custom product cards with renderProductCards, you'll need to handle the target="_blank" attribute in your own HTML.

Example:

$(%DIV_ELEMENT%).preferabliSTP({
    openNewTab: true  // Adds target="_blank" to product links
});

Price Display Settings

Show Decimal Places

Option: showDecimalPlaces
Type: Boolean
Default: true

Description:
Determines whether decimal places are displayed in product prices. When enabled, prices show with decimal precision (e.g., $19.99). When disabled, prices are rounded and displayed as whole numbers (e.g., $20).

Example:

$(%DIV_ELEMENT%).preferabliSTP({
    showDecimalPlaces: true  // Shows $19.99
});

var stp2 = $('#myDiv2').preferabliSTP({
    showDecimalPlaces: false  // Shows $20
});

Number of Decimal Places

Option: numDecimalPlaces
Type: Number
Default: 2

Description:
Specifies exactly how many decimal places to display in product prices. This works in conjunction with showDecimalPlaces. The most common value is 2 (for standard currency formatting like $19.99), but you can adjust this for different currencies or display preferences.

Example:

$(%DIV_ELEMENT%).preferabliSTP({
    showDecimalPlaces: true,
    numDecimalPlaces: 2  // Standard: $19.99
});

Heading Options

Hide Heading

Option: hideHeading
Type: Boolean
Default: false

Description:
Completely hides the heading text that appears above the product recommendations. The heading typically says something like "Recommended for You" or "Similar Products". Use this when you want to provide your own heading in your page HTML or when the widget is embedded in a context where a heading would be redundant.

When hidden, the widget still functions normally but without any title text, giving you a cleaner, more minimalist presentation or allowing you to control the heading separately.

Example:

$(%DIV_ELEMENT%).preferabliSTP({
    hideHeading: true  // No heading will display
});
<!-- You can add your own heading in HTML -->
<h2 class="my-custom-heading">Products You'll Love</h2>
<div id="myDiv"></div>

<script>
$(%DIV_ELEMENT%).preferabliSTP({
    hideHeading: true  // Don't show duplicate heading
});
</script>

Custom Heading Text

Option: customText
Type: Object
Default: null

Description:
Customize the heading text that appears above the product recommendations. The STP widget can return either a single product or multiple products, and this option lets you provide different heading text for each scenario. This is useful for creating more contextual, brand-appropriate messaging.

If not specified, the widget uses default text based on the selected language (see lang option).

Properties:

  • single - Heading text when exactly one product is recommended (e.g., "Our Top Pick for You")
  • multiple - Heading text when two or more products are recommended (e.g., "Recommended Products")

Example:

// For a wine recommendation widget
var stp = $('#wineRecs').preferabliSTP({
    customText: {
        single: 'The Perfect Wine for You',
        multiple: 'Your Personalized Wine Selection'
    }
});

Localization

Language Support

Option: lang
Type: String
Default: 'en'

Description:
Sets the display language for all text in the STP widget, including headings, labels, and UI elements. This enables you to provide a localized experience for international customers. The widget will automatically translate default headings, "Powered by" text, and other interface elements into the selected language.

Note that this only affects the widget's UI text. Your custom product card content and descriptions would need to be localized separately through your e-commerce platform or renderProductCards function.

Supported Languages:

LanguageCode
Englishen
Spanishes
Frenchfr
Germande
Italianit
Koreanko
Portuguesept
Chinese Simplifiedzh_CN
English (Great Britian)en_GB

Example:

// Spanish language site
$(%DIV_ELEMENT%).preferabliSTP({
    lang: 'es'
});

Allowed Languages

Option: allowedLanguage
Type: Array of String
Default: null (all languages allowed)

Description:
Restricts which languages can be displayed in the widget. When set, the widget will only use languages from this list, even if the user's browser or lang setting requests a different language. If the requested language is not in the allowed list, the widget will fall back to the defaultLanguage.

This is useful for sites that only support a specific subset of languages or when you want to ensure consistency across your site's supported languages. For example, if your product catalog is only available in English, Spanish, and French, you can restrict the widget to only those languages.

Example:

// Only allow English, Spanish, and French
$(%DIV_ELEMENT%).preferabliSTP({
    allowedLanguage: ['en', 'es', 'fr'],
    defaultLanguage: 'en'  // Fallback if user's language isn't allowed
});

Default Language

Option: defaultLanguage
Type: String
Default: 'en'

Description:
Sets the fallback language to use when the requested language is not available or not in the allowedLanguage list. This ensures the widget always displays in a language you support, even when the user's browser language or lang setting specifies an unsupported language.

The defaultLanguage should always be included in your allowedLanguage array (if you're using that option) and should be a language you've fully tested and localized for.

Example:

// English as fallback for European site
$(%DIV_ELEMENT%).preferabliSTP({
    allowedLanguage: ['en', 'es', 'fr', 'de', 'it'],
    defaultLanguage: 'en'
});


Tracking

Enables disabling of tracking when a user declines cookie consent, ensuring compliance with privacy regulations by respecting the user’s cookie preferences.

Opt Out Tracking

Option: opt_out_tracking
Type: Boolean
Default: false

Description:
Allows you to opt a user out of tracking based on cookie consent or privacy preferences.
When enabled, tracking-related data will not be collected for the session.

This is typically triggered after a user declines cookies or opts out via a privacy control.

Example:

$(%DIV_ELEMENT%).preferabliSTP({
    ...configuration_settings,
    opt_out_tracking: false,
});
//
$(BUTTON).on('click', function() {
  $(%DIV_ELEMENT%).preferabliSTP('optOutTracking', true);
});

**Notes:**
- Can be toggled dynamically after initialization
- Recommended to integrate with your site's cookie consent manager
- Applies to all instances of Preferabli Widgets

Branding

All branding options are nested within the display object. These options control how the Preferabli logo and branding appears in the widget.

Logo Type

Option: use_preferabli_logo
Type: Boolean
Default: false

Description:
Switches between two branding styles: "Powered by Preferabli" (when false) or just the "Preferabli" logo (when true).

Example:

// Prominent "Powered by Preferabli" branding
$(%DIV_ELEMENT%).preferabliSTP({
    display: {
        use_preferabli_logo: false  // Shows "Powered by" text
    }
});

// Subtle Preferabli logo only
var stp2 = $('#myDiv2').preferabliSTP({
    display: {
        use_preferabli_logo: true  // Just the logo
    }
});

Logo Position

Option: logo_placement
Type: String
Default: 'top'
Values: 'top' | 'bottom'

Description:
Controls whether the Preferabli branding appears above or below the product recommendations. The placement can affect the visual hierarchy and user attention flow on your page.

Top placement gives immediate attribution and brand visibility, while bottom placement keeps the focus on products first and provides attribution after the user has engaged with the recommendations.

Example:

// Logo at top (default)
$(%DIV_ELEMENT%).preferabliSTP({
    display: {
        logo_placement: 'top'
    }
});

// Logo at bottom
var stp2 = $('#myDiv2').preferabliSTP({
    display: {
        logo_placement: 'bottom'
    }
});

Logo Style Options

Option: logo_option
Type: String or Number
Default: 1

Description:
Selects from 8 different visual styles for the Preferabli branding. Each option offers different color combinations and formats (wordmark vs logomark) to match your site's design and color scheme. The options available depend on whether you're using "Powered by Preferabli" or just the "Preferabli" logo (controlled by use_preferabli_logo).

Choose a style that complements your site's color scheme and branding. Two-tone options offer more visual interest, while single-color options are cleaner and more subtle. Wordmarks are more prominent and readable, while logomarks are more compact.

"Powered By Preferabli" Logo Options:

OptionTypeColorsDescriptionBest For
1WordmarkTwo ToneGreen "Powered By" / Blue "Preferabli"Default, balanced branding
2WordmarkTwo ToneGreen "Powered By" / White "Preferabli"Dark backgrounds
3WordmarkSingleBlueClean, professional look
4WordmarkSingleWhiteDark backgrounds, minimal design
5LogomarkTwo ToneGreen "Powered By" / Blue PCompact, colorful
6LogomarkTwo ToneGreen "Powered By" / White PDark backgrounds, compact
7LogomarkSingleBlueMinimal, professional
8LogomarkSingleWhiteDark backgrounds, very minimal

"Preferabli" Logo Options (when use_preferabli_logo: true):

OptionTypeColorsDescriptionBest For
1WordmarkTwo ToneGreen Colon / Blue "Preferabli"Default, balanced
2WordmarkTwo ToneWhite Colon / Blue "Preferabli"Dark backgrounds
3WordmarkSingleBlueClean, professional
4WordmarkSingleWhiteDark backgrounds
5LogomarkTwo ToneGreen Colon / Blue P with textCompact with branding
6LogomarkTwo ToneGreen Colon / White P with textDark backgrounds, compact
7LogomarkSingleBlueVery minimal
8LogomarkSingleWhiteDark backgrounds, very minimal

View all logo variations at: https://brand.preferabli.com/

Example:

// Two-tone wordmark (default)
$(%DIV_ELEMENT%).preferabliSTP({
    display: {
        use_preferabli_logo: false,
        logo_option: 1
    }
});

// White logo for dark background
var stp2 = $('#darkSection').preferabliSTP({
    display: {
        use_preferabli_logo: false,
        logo_option: 4  // White single-color wordmark
    }
});

// Minimal blue logomark
var stp3 = $('#minimal').preferabliSTP({
    display: {
        use_preferabli_logo: true,
        logo_option: 7  // Blue logomark only
    }
});

Logo Text & HTML

Options: logo_before | logo_after
Type: String
Default: null

Description:
Add custom text or HTML before (logo_before) or after (logo_after) the Preferabli logo. This is useful for adding context, additional branding, section titles, or other descriptive text around the logo. You can use plain text or HTML markup for formatting.

Common uses include adding section headers, combining your brand with Preferabli branding, or providing additional context about the recommendations.

Example:

// Add plain text before and after
$(%DIV_ELEMENT%).preferabliSTP({
    display: {
        logo_before: 'Discover ',
        logo_after: ' - Similar Tasting Products'
    }
});
// Result: "Discover [Preferabli Logo] - Similar Tasting Products"

// Add HTML for formatting
var stp2 = $('#myDiv2').preferabliSTP({
    display: {
        logo_before: '<span class="section-label">Recommended by</span> ',
        logo_after: ''
    }
});
// Result: "<span>Recommended by</span> [Preferabli Logo]"

// Add icon before logo
var stp3 = $('#myDiv3').preferabliSTP({
    display: {
        logo_before: '<i class="icon-star"></i> ',
        logo_after: ' Selections'
    }
});
// Result: "<i class="icon-star"></i> [Preferabli Logo] Selections"

Logo Styling

Inline Styles

Option: logo_inline_style
Type: String
Default: null

Description:
Apply CSS styles directly to the logo element using inline style attributes. This is useful for quick styling adjustments without modifying your stylesheet. You can control spacing, opacity, sizing, and other visual properties.

Use standard CSS property syntax (e.g., margin-top: 20px; opacity: 0.8;). Multiple properties can be separated by semicolons.

Example:

// Add spacing and reduce opacity
$(%DIV_ELEMENT%).preferabliSTP({
    display: {
        logo_inline_style: 'margin-top: 20px; opacity: 0.8;'
    }
});

// Center align with spacing
var stp2 = $('#myDiv2').preferabliSTP({
    display: {
        logo_inline_style: 'margin: 30px auto; display: block; text-align: center;'
    }
});

// Subtle grayscale effect
var stp3 = $('#myDiv3').preferabliSTP({
    display: {
        logo_inline_style: 'filter: grayscale(50%); margin-bottom: 15px;'
    }
});

// Adjust size
var stp4 = $('#myDiv4').preferabliSTP({
    display: {
        logo_inline_style: 'transform: scale(0.9); margin: 10px 0;'
    }
});

CSS Classes

Option: logo_class
Type: String
Default: null

Description:
Add one or more custom CSS classes to the logo element. This allows you to style the logo using your existing stylesheet and maintain consistent styling across your site. Classes can be used for responsive design, theme variations, or reusable styling patterns.

Multiple classes should be separated by spaces. These classes are added to the logo in addition to Preferabli's default classes, so you can override or extend the default styling.

Example:

// Single class
$(%DIV_ELEMENT%).preferabliSTP({
    display: {
        logo_class: 'my-custom-logo'
    }
});

// Multiple classes for responsive design
var stp2 = $('#myDiv2').preferabliSTP({
    display: {
        logo_class: 'widget-logo mt-4 mb-3 text-center'
    }
});

// Theme-based class
var stp3 = $('#myDiv3').preferabliSTP({
    display: {
        logo_class: 'dark-theme-logo'
    }
});

Separator

Option: separator
Type: Object
Default: null

Description:
Add horizontal separator lines (borders) above and/or below the STP widget content. Separators help visually distinguish the recommendations section from surrounding content on your page. You can customize the appearance (color, thickness, style) and spacing of the separators.

This is particularly useful when embedding the widget in content-heavy pages where visual separation improves readability and draws attention to the recommendations.

Properties:

  • show - Where to display separators:
    • 'top' - Only above the widget
    • 'bottom' - Only below the widget
    • 'both' - Above and below the widget
  • style - Styling object that applies to both separators (or individually):
    • border_width - Thickness of the line (e.g., '1px', '2px')
    • border_color - Color of the line (any CSS color: '#ccc', 'rgba(0,0,0,0.1)', 'gray')
    • border_style - Line style: 'solid', 'dashed', 'dotted', 'double'
    • spacing_top - Space above the separator line
    • spacing_bottom - Space below the separator line You can also specify different styles for top and bottom separators individually.

Example (Simple - Same Style for Both):

$(%DIV_ELEMENT%).preferabliSTP({
    display: {
        separator: {
            show: 'both',  // Show above and below
            style: {
                border_width: '2px',
                border_color: '#cccccc',
                border_style: 'solid',
                spacing_top: '20px',
                spacing_bottom: '20px'
            }
        }
    }
});

Example (Individual Separator Styling):

// Different styles for top and bottom separators
var stp2 = $('#myDiv2').preferabliSTP({
    display: {
        separator: {
            show: 'both',
            style: {
                top: {
                    border_width: '1px',
                    border_color: '#dddddd',
                    border_style: 'solid',
                    spacing_top: '10px',
                    spacing_bottom: '15px'
                },
                bottom: {
                    border_width: '2px',
                    border_color: '#999999',
                    border_style: 'dashed',
                    spacing_top: '20px',
                    spacing_bottom: '10px'
                }
            }
        }
    }
});

Example (Top Only with Subtle Style):

// Only top separator with subtle styling
var stp3 = $('#myDiv3').preferabliSTP({
    display: {
        separator: {
            show: 'top',
            style: {
                border_width: '1px',
                border_color: 'rgba(0, 0, 0, 0.1)',  // Very subtle
                border_style: 'solid',
                spacing_top: '30px',
                spacing_bottom: '30px'
            }
        }
    }
});

Complete Example

Here's a comprehensive configuration example that combines multiple options to create a fully customized STP widget:

var stp = $('#productRecommendations').preferabliSTP({
    // ===================
    // API Configuration
    // ===================
    integration_id: 'your-api-key-here',
    collection_id: '12345',
    
    // ===================
    // Product Cards
    // ===================
    // Use custom Shopify/WooCommerce product cards
    renderProductCards: (lookups) => {
        const valid = lookups.filter(l => l.landing_url);
        return Promise.all(
            valid.map(l =>
                fetch(`${l.landing_url}?view=stp`)
                    .then(r => r.ok ? r.text() : null)
                    .then(html => html ? `${html}` : null)
                    .catch(() => null)
            )
        ).then(results => results.filter(Boolean));
    },
    
    // Match ecommerce structure
    productCardsContainer: {
        element: 'ul',
        class: 'products columns-3',
        id: 'stp-recommendations'
    },
    
    // Initialize functions after render
    onRenderComplete: function() {
    },
    
    // ===================
    // Display Options
    // ===================
    devMode: false,              // Show to all users
    openNewTab: true,            // Open products in new tab
    showDecimalPlaces: true,     // Show .99 prices
    numDecimalPlaces: 2,         // Standard currency format
    hideHeading: false,          // Show the heading
    
    // Custom heading text
    customText: {
        single: 'Perfect Match for You',
        multiple: 'You Might Also Love'
    },
    
    // ===================
    // Localization
    // ===================
    lang: 'en',                          // Display language
    allowedLanguage: ['en', 'es', 'fr'], // Restrict to these languages
    defaultLanguage: 'en',               // Fallback language
    
    // ===================
    // Branding & Logo
    // ===================
    display: {
        use_preferabli_logo: false,      // Show "Powered by Preferabli"
        logo_placement: 'bottom',        // Logo below products
        logo_option: 1,                  // Two-tone wordmark
        
        // Add context text
        logo_before: '',
        logo_after: 'Personalized Recommendations',
        
        // Style the logo
        logo_inline_style: 'margin-top: 25px; opacity: 0.9;',
        logo_class: 'text-center my-logo',
        
        // Add visual separators
        separator: {
            show: 'both',
            style: {
                // Top separator - subtle
                top: {
                    border_width: '1px',
                    border_color: '#e5e5e5',
                    border_style: 'solid',
                    spacing_top: '40px',
                    spacing_bottom: '30px'
                },
                // Bottom separator - more prominent
                bottom: {
                    border_width: '2px',
                    border_color: '#cccccc',
                    border_style: 'solid',
                    spacing_top: '30px',
                    spacing_bottom: '40px'
                }
            }
        }
    }
});

Example: Minimal Configuration

For a quick, simple setup with defaults:

var stp = $('#recommendations').preferabliSTP({
    intergration_id: 'your-api-key-here',
    collection_id: '12345'
});

Example: Dark Theme Site

Configuration optimized for a dark background:

var stp = $('#darkSite').preferabliSTP({
    intergration_id: 'your-api-key-here',
    collection_id: '12345',
    display: {
        logo_option: 4,  // White single-color wordmark
        logo_inline_style: 'opacity: 0.8;',
        separator: {
            show: 'both',
            style: {
                border_color: 'rgba(255, 255, 255, 0.2)',  // Light border
                border_width: '1px',
                border_style: 'solid',
                spacing_top: '30px',
                spacing_bottom: '30px'
            }
        }
    }
});