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 containerid- 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:
- Enable
devMode: truein your configuration - Load the page in your browser
- Open Developer Tools (F12 or right-click → Inspect)
- Find the
.stp__containerelement - Disable or remove the
display: nonestyle - 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:
| Language | Code |
|---|---|
| English | en |
| Spanish | es |
| French | fr |
| German | de |
| Italian | it |
| Korean | ko |
| Portuguese | pt |
| Chinese Simplified | zh_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 WidgetsBranding
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:
| Option | Type | Colors | Description | Best For |
|---|---|---|---|---|
| 1 | Wordmark | Two Tone | Green "Powered By" / Blue "Preferabli" | Default, balanced branding |
| 2 | Wordmark | Two Tone | Green "Powered By" / White "Preferabli" | Dark backgrounds |
| 3 | Wordmark | Single | Blue | Clean, professional look |
| 4 | Wordmark | Single | White | Dark backgrounds, minimal design |
| 5 | Logomark | Two Tone | Green "Powered By" / Blue P | Compact, colorful |
| 6 | Logomark | Two Tone | Green "Powered By" / White P | Dark backgrounds, compact |
| 7 | Logomark | Single | Blue | Minimal, professional |
| 8 | Logomark | Single | White | Dark backgrounds, very minimal |
"Preferabli" Logo Options (when use_preferabli_logo: true):
| Option | Type | Colors | Description | Best For |
|---|---|---|---|---|
| 1 | Wordmark | Two Tone | Green Colon / Blue "Preferabli" | Default, balanced |
| 2 | Wordmark | Two Tone | White Colon / Blue "Preferabli" | Dark backgrounds |
| 3 | Wordmark | Single | Blue | Clean, professional |
| 4 | Wordmark | Single | White | Dark backgrounds |
| 5 | Logomark | Two Tone | Green Colon / Blue P with text | Compact with branding |
| 6 | Logomark | Two Tone | Green Colon / White P with text | Dark backgrounds, compact |
| 7 | Logomark | Single | Blue | Very minimal |
| 8 | Logomark | Single | White | Dark 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 linespacing_bottom- Space below the separator line You can also specify different styles fortopandbottomseparators 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'
}
}
}
});Updated 5 days ago
