RecommendedBy Widget

Migration Notice: We are transitioning from <bw-widget> to <nw-blocks> tags. While both are currently supported for backward compatibility, <nw-blocks> is now the recommended tag for all new implementations. Existing <bw-widget> implementations will continue to function.

Overview

The RecommendedBy widget displays a horizontally scrollable carousel of recommended casino or betting brands with their logos, ratings, and review links. Features smooth virtual scrolling on desktop (≥768px) and native touch scrolling on mobile, making it perfect for showcasing trusted brands, expert recommendations, and related casino suggestions.

Key Features:

  • Horizontal Scroll Carousel: Smooth virtual scroll on desktop, native touch on mobile
  • Brand Cards: Logo, star rating, and custom text per brand
  • Review Links: Direct links to individual brand review pages
  • Custom Heading: Configurable heading text, level (H1-H6), and alignment
  • Custom Text: Per-brand text with translation key support
  • Star Ratings: Visual rating display (0-5 stars)
  • Tracking Integration: Built-in tracking link generation with widget ID
  • Responsive Design: Desktop virtual scroll, mobile touch-friendly
  • Virtual Scrolling: Enhanced smooth scrolling with easing and amplification
  • SEO Optimized: Proper heading levels and nofollow links

Basic Usage

Expand me...

Attributes Reference

Attribute Type Required Default Description
id string Yes - Must be “recommendedby”
recommendedID string Yes - Recommended group identifier from CMS
language string No “en” ISO 639-1 language code
country string No “ZZ” ISO 3166-1 country code
headingtext string No - Custom heading text
headinglevel string No “h1” Heading level (h1, h2, h3, h4, h5, h6, p)
headingalignment string No “Center” Heading alignment (Left, Center, Right)
textkey string No - Translation key for brand link text
text string No - Custom text for brand links (overrides textkey)
rel string No “nofollow” Link rel attribute
target string No “_blank” Link target attribute
trackinglinktarget string No - Tracking link target parameter

Widget Components

Heading Section

Display:

  • Shows custom heading text via headingtext attribute
  • Configurable heading level (H1-H6) for SEO
  • Alignment control (left, center, right)

SEO Considerations:

  • Use H1 only once per page
  • Use H2-H3 for section headings
  • Maintain logical heading hierarchy

Desktop (≥768px):

  • Virtual horizontal scrolling
  • Smooth easing animation (0.1 ease factor)
  • Scroll amplification (1.25x)
  • Mouse wheel support
  • Enhanced UX with momentum

Mobile (<768px):

  • Native touch scrolling
  • Swipe gestures
  • Momentum scrolling
  • No virtual scroll overhead

Technical Implementation:

useVirtualHorizontalScroll(viewportRef, trackRef, {
  minWidth: 768,      // Activate on desktop only
  ease: 0.1,          // Smooth easing
  amplify: 1.25       // Scroll amplification
});

Brand Cards

Each brand card displays:

Logo Section:

  • Brand logo image
  • Clickable to tracking link
  • Responsive sizing
  • Alt text from CMS

Rating Section:

  • Star rating display (0-5)
  • SVG sprite for consistent rendering
  • Visual feedback of brand quality

Review Link:

  • Custom text or translation key
  • Links to brand review page
  • Configurable target and rel

Card Structure:

{
  cloakedLink: "brand-casino",
  rating: 4.5,
  imgSrc: "/brands/logo.png",
  reviewLink: "/brand-casino-review",
  text: "Read Review"
}

URL Structure:

/go/{cloakedLink}/{provider}?wid={widgetId}

Components:

  • cloakedLink: Brand identifier
  • provider: Tracking provider (default: “out”)
  • wid: Widget ID for analytics

Example:

/go/fresh-casino/out?wid=recommendedby-123

Virtual Horizontal Scroll

Desktop Implementation

Features:

  • Smooth scrolling animation
  • Mouse wheel support
  • Easing for natural feel
  • Scroll amplification
  • No scrollbar (custom implementation)

Configuration:

{
  minWidth: 768,      // Only activate ≥768px
  ease: 0.1,          // Smoothing factor (lower = smoother)
  amplify: 1.25       // Scroll speed multiplier
}

How It Works:

  1. Tracks mouse wheel delta
  2. Applies easing animation
  3. Amplifies scroll distance
  4. Updates viewport position
  5. Smooth frame-by-frame updates

Mobile Implementation

Features:

  • Native touch scrolling
  • Horizontal swipe gestures
  • Momentum scrolling
  • Browser-optimized performance

Benefits:

  • No JavaScript overhead
  • Native feel
  • Better performance
  • Accessibility support

Inline Script Injection

For WordPress and non-React environments:

const script = generateVirtualHorizontalScrollScript(
  '#recommendedby-viewport',
  '#recommendedby-track',
  {
    minWidth: 768,
    ease: 0.1,
    amplify: 1.25
  }
);

Injects self-contained JavaScript for virtual scrolling functionality.


Common Use Cases

Homepage Recommendations

<nw-blocks
    id="recommendedby"
    recommendedID="homepage-featured-casinos"
    language="en"
    country="UK"
    headingtext="Featured Online Casinos"
    headinglevel="h2"
    headingalignment="center"
    text="Visit Casino" \>
</nw-blocks>

Review Page Suggestions

<nw-blocks
    id="recommendedby"
    recommendedID="similar-casinos-888"
    language="en"
    country="UK"
    headingtext="Similar Casinos You Might Like"
    headinglevel="h3"
    headingalignment="left"
    textkey="wgt-read-full-review" \>
</nw-blocks>

Category Page Recommendations

<nw-blocks
    id="recommendedby"
    recommendedID="best-live-casinos"
    language="en"
    country="UK"
    headingtext="Best Live Dealer Casinos"
    headinglevel="h2"
    text="Explore Casino" \>
</nw-blocks>

Multi-Language Recommendations

<!-- English -->
<nw-blocks
    id="recommendedby"
    recommendedID="recommended-casinos-en"
    language="en"
    country="UK"
    headingtext="Recommended Casinos"
    text="Read Review" \>
</nw-blocks>

<!-- French -->
<nw-blocks
    id="recommendedby"
    recommendedID="recommended-casinos-fr"
    language="fr"
    country="FR"
    headingtext="Casinos Recommandés"
    text="Lire l'avis" \>
</nw-blocks>

<!-- Spanish -->
<nw-blocks
    id="recommendedby"
    recommendedID="recommended-casinos-es"
    language="es"
    country="ES"
    headingtext="Casinos Recomendados"
    text="Leer Reseña" \>
</nw-blocks>

<!-- German -->
<nw-blocks
    id="recommendedby"
    recommendedID="recommended-casinos-de"
    language="de"
    country="DE"
    headingtext="Empfohlene Casinos"
    text="Bewertung Lesen" \>
</nw-blocks>

<!-- Portuguese -->
<nw-blocks
    id="recommendedby"
    recommendedID="recommended-casinos-pt"
    language="pt"
    country="BR"
    headingtext="Cassinos Recomendados"
    text="Ler Avaliação" \>
</nw-blocks>

Sports Betting Recommendations

<nw-blocks
    id="recommendedby"
    recommendedID="top-sportsbooks"
    language="en"
    country="UK"
    headingtext="Top Rated Sportsbooks"
    headinglevel="h2"
    text="View Sportsbook" \>
</nw-blocks>

Regional Recommendations (US States)

<!-- New Jersey -->
<nw-blocks
    id="recommendedby"
    recommendedID="nj-approved-casinos"
    language="en"
    country="US"
    headingtext="NJ Licensed Online Casinos"
    text="Play Now" \>
</nw-blocks>

<!-- Pennsylvania -->
<nw-blocks
    id="recommendedby"
    recommendedID="pa-casinos"
    language="en"
    country="US"
    headingtext="PA Legal Online Casinos"
    text="Join Now" \>
</nw-blocks>

Editor’s Pick Section

<nw-blocks
    id="recommendedby"
    recommendedID="editors-choice-2025"
    language="en"
    country="UK"
    headingtext="Editor's Choice 2025"
    headinglevel="h2"
    headingalignment="center"
    textkey="wgt-editors-pick-cta" \>
</nw-blocks>
<nw-blocks
    id="recommendedby"
    recommendedID="footer-partner-casinos"
    language="en"
    country="UK"
    headingtext="Our Partner Casinos"
    headinglevel="h4"
    headingalignment="center"
    text="Learn More" \>
</nw-blocks>

Best Practices

Content Strategy

  • Relevant Grouping: Group related brands in CMS via recommendedID
  • Clear Headings: Use descriptive heading text that explains recommendation context
  • Appropriate Heading Levels: Maintain SEO hierarchy (H1 → H2 → H3)
  • Call-to-Action: Use clear CTA text (“Read Review”, “Visit Casino”, “Play Now”)
  • Quality Ratings: Display only brands with ratings ≥3.5 for credibility

UX Optimization

  • Visible Cards: Show 3-5 brand cards on initial view
  • Scroll Indication: Ensure users know more brands are available (shadows, partial cards)
  • Mobile Touch: Test swipe gestures on mobile devices
  • Quick Load: Lazy load brand logos below the fold
  • Consistent Branding: Use consistent logo sizes and aspect ratios

Visual Design

  • Card Spacing: Adequate gap between cards for clarity
  • Logo Quality: Use high-resolution logos (minimum 200px width)
  • Rating Display: Clear, consistent star rating visualization
  • Alignment: Center alignment works best for recommendation sections
  • Hover States: Provide visual feedback on card hover (desktop)

Performance

  • Virtual Scroll: Only activates on desktop (≥768px)
  • Lazy Loading: Consider lazy loading logos
  • Minimal Scripts: Inline script is compact and efficient
  • Cache Strategy: Brand data cached in KV storage
  • Image Optimization: Use WebP format for logos

Accessibility

  • Keyboard Navigation: Ensure cards are keyboard accessible
  • Focus States: Visible focus indicators on cards and links
  • Screen Readers: Descriptive alt text for brand logos
  • Skip Links: Consider skip navigation for long carousels
  • Touch Targets: Minimum 44px touch target size on mobile

SEO Optimization

  • Heading Hierarchy: Use proper heading levels (H1 once, H2-H3 for sections)
  • Nofollow Links: Use rel="nofollow" for affiliate links
  • Descriptive Text: Clear link text instead of “Click here”
  • Alt Text: Descriptive alt attributes for brand logos
  • Semantic HTML: Proper HTML structure for carousel

Advanced Configuration

Custom Scroll Settings

Modify scroll behavior via configuration:

// Smoother scrolling (lower ease)
{
  minWidth: 768,
  ease: 0.05,        // Very smooth
  amplify: 1.0       // Normal speed
}

// Faster scrolling
{
  minWidth: 768,
  ease: 0.15,        // Less smooth
  amplify: 1.5       // 1.5x speed
}

// Tablet and up
{
  minWidth: 600,     // Activate on tablets
  ease: 0.1,
  amplify: 1.25
}

Multiple Recommendation Sections

<!-- Top recommendations -->
<nw-blocks
    id="recommendedby-top"
    recommendedID="top-tier-casinos"
    headingtext="Top Tier Casinos"
    headinglevel="h2" \>
</nw-blocks>

<!-- New casinos -->
<nw-blocks
    id="recommendedby-new"
    recommendedID="new-casinos-2025"
    headingtext="New Casinos 2025"
    headinglevel="h2" \>
</nw-blocks>

<!-- High rollers -->
<nw-blocks
    id="recommendedby-vip"
    recommendedID="high-roller-casinos"
    headingtext="High Roller Casinos"
    headinglevel="h2" \>
</nw-blocks>

Configure tracking provider in CMS:

websiteConfiguration: {
  trackingLinkProvider: "out"  // Default
  // or: "homepage", "review", "bonus"
}

Translation Key Usage

Define translation keys in i18n:

{
  "wgt-recommendedby-cta": "Read Full Review",
  "wgt-editors-pick-cta": "Editor's Choice",
  "wgt-recommended-new": "New Casino",
  "wgt-recommended-play": "Play Now"
}

Usage:

<nw-blocks
    id="recommendedby"
    recommendedID="..."
    textkey="wgt-recommendedby-cta" \>
</nw-blocks>

Data Requirements

Sanity CMS Structure

Widget fetches recommended brands group:

{
  recommendedID: "recommended-sb-www-localwebstite-com-general-brand",
  isActive: true,
  websiteConfiguration: {
    trackingLinkProvider: "out"
  },
  recommendedBrands: [
    {
      cloakedLink: "fresh-casino",
      brandName: "888 Casino",
      rating: 4.7,
      imgSrc: "https://cdn.example.com/brands/fresh-casino-logo.png",
      reviewLink: "/888-casino-review",
      text: "Read Review",
      textKey: "wgt-read-review",
      alt: "888 Casino Logo",
      displayOrder: 1
    },
    {
      cloakedLink: "leovegas-casino",
      brandName: "LeoVegas Casino",
      rating: 4.6,
      imgSrc: "https://cdn.example.com/brands/leovegas-logo.png",
      reviewLink: "/leovegas-casino-review",
      text: "Read Review",
      textKey: "wgt-read-review",
      alt: "LeoVegas Casino Logo",
      displayOrder: 2
    },
    {
      cloakedLink: "betsson-casino",
      brandName: "Betsson Casino",
      rating: 4.5,
      imgSrc: "https://cdn.example.com/brands/betsson-logo.png",
      reviewLink: "/betsson-casino-review",
      text: "Read Review",
      textKey: "wgt-read-review",
      alt: "Betsson Casino Logo",
      displayOrder: 3
    }
    // ... more brands
  ]
}

Required Fields:

  • recommendedID: Group identifier
  • isActive: Widget status
  • recommendedBrands: Array of brand objects

Brand Object Fields:

  • cloakedLink: Brand identifier (required)
  • rating: Star rating 0-5 (required)
  • imgSrc: Logo URL (required)
  • reviewLink: Review page URL (required)
  • text: Link text (optional if textKey provided)
  • textKey: Translation key (optional)
  • alt: Logo alt text (required)
  • displayOrder: Sorting order (optional)

Optional Fields:

  • websiteConfiguration.trackingLinkProvider: Tracking provider
  • brandName: Brand name for reference
  • textKey: i18n translation key

Translation Keys

Required i18n keys:

{
  "recommendedby-revue": "Read Review",
  "wgt-read-review": "Read Review",
  "wgt-read-full-review": "Read Full Review",
  "wgt-visit-casino": "Visit Casino",
  "wgt-play-now": "Play Now",
  "wgt-editors-pick-cta": "Editor's Choice",
  "wgt-recommendedby-cta": "Learn More"
}

Language-Specific Examples:

{
  "en": {
    "recommendedby-revue": "Read Review",
    "wgt-visit-casino": "Visit Casino"
  },
  "fr": {
    "recommendedby-revue": "Lire l'avis",
    "wgt-visit-casino": "Visiter le Casino"
  },
  "es": {
    "recommendedby-revue": "Leer Reseña",
    "wgt-visit-casino": "Visitar Casino"
  },
  "de": {
    "recommendedby-revue": "Bewertung Lesen",
    "wgt-visit-casino": "Casino Besuchen"
  },
  "pt": {
    "recommendedby-revue": "Ler Avaliação",
    "wgt-visit-casino": "Visitar Cassino"
  }
}

KV Storage

Recommended brands data is cached:

  • Key: RECOMMENDED:{recommendedID}:{country}:{language}
  • TTL: 1 hour
  • Invalidation: On brand/recommendation update

Error Handling

Inactive Widget

If widget is inactive:

<p id="inactive-brand" style="display: none;">
  This widget is inactive or not allowed in this country.
</p>

Handling:

  • Widget shows hidden error message
  • No visual output to users
  • Check isActive flag in CMS
  • Verify regional availability

No Brands

If no recommended brands:

  • Widget renders empty
  • Consider fallback message
  • Check recommendedBrands array in CMS

Missing Brand Data

Missing Logo:

  • Image placeholder or broken image
  • Alt text displays brand name
  • Ensure all logos uploaded to CDN

Missing Rating:

  • Default to 0 stars or hide rating section
  • Validate rating data in CMS

Missing Review Link:

  • Card remains clickable to tracking link
  • Ensure review pages exist

JavaScript Disabled

If JavaScript disabled:

  • Horizontal scroll still works (native CSS overflow)
  • No virtual scrolling (falls back to standard scroll)
  • Cards remain clickable
  • Graceful degradation to standard scrollable container

Comparison: Recommendation Widgets

Feature RecommendedBy PuzzleTop Hero2
Display Type Horizontal carousel Vertical list Single/multi-row
Scrolling Virtual horizontal Vertical page No scroll
Brand Count Multiple (carousel) Multiple (list) 1-4
Rating Display ✅ Stars ✅ Stars ✅ Stars
Review Links ✅ Yes ⚠️ Optional ⚠️ Optional
Bonus Display ❌ No ✅ Yes ✅ Yes
Use Case Related recommendations Top lists Featured brand
Mobile ✅ Touch scroll ✅ Standard ✅ Responsive

When to use RecommendedBy:

  • Related brand recommendations
  • “You might also like” sections
  • Horizontal space available
  • Multiple brand showcase
  • Review page suggestions
  • Category page recommendations

When to use PuzzleTop/Hero:

  • Detailed toplist with rankings
  • Featured single brand
  • Bonus information needed
  • Vertical layout preferred

Backward Compatibility

All examples above use the new <nw-blocks> tag. For backward compatibility, you can still use <bw-widget>:

<!-- Old syntax (still supported) -->
<bw-widget
    id="recommendedby"
    recommendedID="recommended-sb-www-localwebstite-com-general-brand"
    language="en"
    country="UK"
    headingtext="Recommended Casinos"
    headinglevel="h2"
    headingalignment="center"
    textkey="recommendedby-revue"
    text="Read Review" \>
</bw-widget>

<!-- New syntax (recommended) -->
<nw-blocks
    id="recommendedby"
    recommendedID="recommended-sb-www-localwebstite-com-general-brand"
    language="en"
    country="UK"
    headingtext="Recommended Casinos"
    headinglevel="h2"
    headingalignment="center"
    textkey="recommendedby-revue"
    text="Read Review" \>
</nw-blocks>

Both tags work identically, but <nw-blocks> is recommended for all new implementations.