Skip to content

Configure Recommendation Widgets

⏱ 15 minutes intermediate

A recommendation model running in the background produces nothing visible to visitors. Widgets are the delivery mechanism β€” they render recommended content on your pages where visitors can see and interact with the suggestions. The widget placement, style, and behavior directly affect whether visitors engage with recommendations.

  1. Choose a widget type for your use case
  2. Add a widget to a page
  3. Configure display options
  4. Handle empty and fallback states
  5. Style the widget to match your design

Content Recommendations supports several widget formats. Choose based on placement and content type.

Widget typeLayoutBest for
CarouselHorizontally scrollable cardsArticle sidebars, homepage sections
GridFixed grid of cards (2x2, 3x1, etc.)Blog footers, category pages
ListVertical list with thumbnailsSidebar widgets, mobile layouts
InlineSingle recommendation embedded in textMid-article suggestions
OverlayModal or slide-in panelExit intent, engagement triggers

Add the widget code where you want recommendations to appear.

Embed a recommendation widget
html
<!-- Container for the widget -->
<div id="content-recommendations-widget"></div>

<script>
window.optimizelyContentRecs = window.optimizelyContentRecs || [];

window.optimizelyContentRecs.push({
  action: 'renderWidget',
  selector: '#content-recommendations-widget',
  modelId: 'YOUR_MODEL_ID',
  widgetType: 'grid',
  options: {
    count: 4,
    showImage: true,
    showDescription: true,
    maxDescriptionLength: 120,
    openInNewTab: false,
  },
});
</script>

Replace YOUR_MODEL_ID with the ID from your recommendation model (found in Content Recommendations > Models > [Your Model] > Settings).

For CMS PaaS, the recommendation widget can be implemented as a custom block type that wraps the JavaScript embed code. This gives editors control over placement while developers control the rendering logic.

Control what information each recommended item displays:

OptionTypeDefaultDescription
countinteger4Number of recommendations to show
showImagebooleantrueDisplay the featured image
showDescriptionbooleantrueDisplay the content description
maxDescriptionLengthinteger150Truncate description at this character count
showCategorybooleanfalseDisplay the content category label
showDatebooleanfalseDisplay the publication date
openInNewTabbooleanfalseOpen recommendation links in a new browser tab
imageAspectRatiostring”16:9”Image crop ratio: β€œ16:9”, β€œ4:3”, β€œ1:1”

Narrow what the widget can display beyond the model’s own rules:

Widget with filters
javascript
window.optimizelyContentRecs.push({
action: 'renderWidget',
selector: '#sidebar-recommendations',
modelId: 'YOUR_MODEL_ID',
widgetType: 'list',
options: {
  count: 5,
  showImage: true,
  showDescription: false,
},
filters: {
  excludeCurrentPage: true,
  contentTypes: ['blog-post', 'guide'],
  categories: ['marketing'],
  maxAge: 90, // only content published within last 90 days
},
});
FilterTypeDescription
excludeCurrentPagebooleanExclude the page the visitor is currently viewing
contentTypesarrayOnly show specific content types
categoriesarrayOnly show content in these categories
maxAgeintegerMaximum content age in days
languagestringOnly show content in this language

Sometimes the recommendation engine cannot fill all slots β€” a new visitor with no history, insufficient data, or aggressive filters. Configure what happens in these cases.

Configure fallback behavior
javascript
window.optimizelyContentRecs.push({
action: 'renderWidget',
selector: '#recommendations',
modelId: 'YOUR_MODEL_ID',
widgetType: 'grid',
options: { count: 4 },
fallback: {
  strategy: 'trending',     // 'trending', 'editorial', or 'hide'
  trendingWindow: '7d',     // for trending strategy: '24h', '7d', '30d'
  editorialItems: [         // for editorial strategy
    { url: '/blog/getting-started/', title: 'Getting Started Guide' },
    { url: '/blog/best-practices/', title: 'Best Practices' },
  ],
  minItems: 2,              // hide widget if fewer than this many items
},
});
StrategyBehavior
trendingFill empty slots with trending content from the same catalog
editorialFill empty slots with a manually curated list
hideHide the widget entirely if not enough recommendations

Widgets render with default CSS classes you can override. The widget generates markup with these classes:

ClassElement
.opti-recs-widgetWidget container
.opti-recs-itemIndividual recommendation card
.opti-recs-imageCard image container
.opti-recs-titleCard title
.opti-recs-descriptionCard description text
.opti-recs-categoryCategory label
.opti-recs-datePublication date

To customize styles, add CSS rules targeting these classes. The widget does not use shadow DOM, so your site styles apply normally.

For complete visual control, use the templateOverride option:

Custom HTML template
javascript
window.optimizelyContentRecs.push({
action: 'renderWidget',
selector: '#custom-recommendations',
modelId: 'YOUR_MODEL_ID',
widgetType: 'grid',
options: { count: 3 },
templateOverride: function(items) {
  return items.map(item =>
    '<a href="' + item.url + '" class="my-rec-card">' +
      '<img src="' + item.image + '" alt="' + item.title + '" />' +
      '<h3>' + item.title + '</h3>' +
    '</a>'
  ).join('');
},
});
  1. Deploy the widget to a staging environment
  2. Browse several pages to build a visitor profile
  3. Navigate to a page with the widget and verify recommendations appear
  4. Check that recommendations change based on browsing context
  5. Test the fallback by opening the page in an incognito window (no visitor history)
  6. Verify that the widget hides or shows fallback content as configured