🔗 Related Content Widget Design

Related content widgets є powerful tools для increasing engagement, session duration, та content discovery. By suggesting relevant articles, guides, або species profiles, ви keep readers exploring deeper into mushroom knowledge base. Well-designed related content reduces bounce rates, improves SEO through internal linking, та provides natural content pathways. Цей guide охоплює recommendation algorithms, layout patterns, metadata usage, та implementation strategies.

🎨 Widget Design Examples

💡 Key Design Elements:

  • ✅ Clear section heading ("Related Articles", "You May Like")
  • ✅ Thumbnail images (visual interest)
  • ✅ Article title (concise, descriptive)
  • ✅ Metadata (category, read time, date)
  • ✅ 3-6 items (Don't overwhelm)
  • ✅ Card-based layout (clickable)
  • ✅ Hover effects (visual feedback)

🧠 Recommendation Algorithms

1. Tag/Category Matching

Logic: Same tags/categories як current article

Example: Article tagged "P. cubensis" + "PF Tek" shows other articles з same tags

Pros: Simple, accurate, no data needed

Cons: Limited diversity

2. Content Similarity (TF-IDF)

Logic: Textual similarity analysis

Implementation: Compare word frequency vectors

Pros: Handles untagged content

Cons: Computationally expensive

3. Author Recommendations

Logic: Manually curated links

Implementation: Metadata field "related_posts"

Pros: High quality, contextual

Cons: Manual work required

4. Popular в Same Category

Logic: Most viewed у same category

Implementation: Analytics data + category filter

Pros: Proven engagement

Cons: Creates "rich get richer" effect

5. Collaborative Filtering

Logic: "Users who read this also read..."

Implementation: User behavior tracking

Pros: Discovers unexpected connections

Cons: Requires много traffic data

6. Hybrid Approach (Recommended)

Logic: Combine multiple methods

Example:

  • 1. Manual picks (if available)
  • 2. Same tags (priority)
  • 3. Popular у category (fallback)

💻 Implementation Example

1. HTML Structure:

<!-- Related Content Widget -->
<aside class="related-content-widget">
  <h3 class="widget-title">🔗 Related Articles</h3>
  <div class="related-articles-grid" id="relatedArticles">
    <!-- Dynamically populated -->
  </div>
</aside>

2. JavaScript (Tag-Based Algorithm):

// Related Content Generator
class RelatedContent {
  constructor(currentArticle, containerSelector, count = 3) {
    this.currentArticle = currentArticle;
    this.container = document.querySelector(containerSelector);
    this.count = count;
    
    // Article data (у production, fetch від API)
    this.allArticles = [
      {
        id: 1,
        title: "Psilocybe Cyanescens: Complete Guide",
        category: "Species",
        tags: ["psilocybe", "wood-loving", "potent"],
        thumbnail: "/images/cyanescens.jpg",
        url: "/species/cyanescens",
        readTime: 8
      },
      {
        id: 2,
        title: "Outdoor Bed Cultivation",
        category: "Growing",
        tags: ["cultivation", "outdoor", "wood-loving"],
        thumbnail: "/images/outdoor.jpg",
        url: "/growing/outdoor-beds",
        readTime: 12
      },
      // ... more articles
    ];
    
    this.init();
  }
  
  init() {
    const related = this.findRelated();
    this.render(related);
  }
  
  findRelated() {
    // Score each article based on similarity
    const scored = this.allArticles
      .filter(article => article.id !== this.currentArticle.id)
      .map(article => ({
        ...article,
        score: this.calculateScore(article)
      }))
      .sort((a, b) => b.score - a.score)
      .slice(0, this.count);
    
    return scored;
  }
  
  calculateScore(article) {
    let score = 0;
    
    // Same category: +10 points
    if (article.category === this.currentArticle.category) {
      score += 10;
    }
    
    // Shared tags: +5 points per tag
    const sharedTags = article.tags.filter(tag =>
      this.currentArticle.tags.includes(tag)
    );
    score += sharedTags.length * 5;
    
    // Recency bonus (optional)
    // const daysSincePublished = ...;
    // score += Math.max(0, 10 - daysSincePublished);
    
    return score;
  }
  
  render(articles) {
    const html = articles.map(article => `
      <a href="${article.url}" class="related-card">
        <div class="related-thumbnail">
          <img src="${article.thumbnail}" alt="${article.title}">
        </div>
        <div class="related-info">
          <h4 class="related-title">${article.title}</h4>
          <div class="related-meta">
            <span class="category">${article.category}</span>
            <span class="read-time">${article.readTime} min read</span>
          </div>
        </div>
      </a>
    `).join('');
    
    this.container.innerHTML = html;
  }
}

// Initialize
document.addEventListener('DOMContentLoaded', () => {
  // Current article metadata (від page)
  const currentArticle = {
    id: 5,
    title: "Psilocybe Azurescens Growing Guide",
    category: "Growing",
    tags: ["psilocybe", "wood-loving", "outdoor", "potent"]
  };
  
  new RelatedContent(currentArticle, '#relatedArticles', 3);
});

3. CSS Styling:

.related-content-widget {
  margin-top: 60px;
  padding: 40px;
  background: #f8f9fa;
  border-radius: 15px;
}

.widget-title {
  font-size: 1.8em;
  font-weight: 700;
  color: #2c3e50;
  margin-bottom: 30px;
}

.related-articles-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 25px;
}

.related-card {
  background: white;
  border-radius: 12px;
  overflow: hidden;
  border: 2px solid #e9ecef;
  text-decoration: none;
  transition: all 0.3s;
  display: block;
}

.related-card:hover {
  border-color: #fbc2eb;
  box-shadow: 0 8px 25px rgba(251, 194, 235, 0.3);
  transform: translateY(-5px);
}

.related-thumbnail {
  width: 100%;
  height: 180px;
  overflow: hidden;
}

.related-thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s;
}

.related-card:hover .related-thumbnail img {
  transform: scale(1.05);
}

.related-info {
  padding: 20px;
}

.related-title {
  font-size: 1.1em;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 10px;
  line-height: 1.4;
}

.related-meta {
  display: flex;
  gap: 15px;
  font-size: 0.9em;
  color: #6c757d;
}

.category {
  font-weight: 600;
  color: #fbc2eb;
}

/* Responsive */
@media (max-width: 1024px) {
  .related-articles-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  .related-articles-grid {
    grid-template-columns: 1fr;
  }
}

⚡ Best Practices

Placement

  • ✅ After article content (primary)
  • ✅ Sidebar (secondary)
  • ✅ In-article (for very long posts)
  • ❌ Before article (distracting)

Quantity

  • ✅ 3-6 items (optimal)
  • ❌ 1-2 items (too few)
  • ❌ 10+ items (overwhelming)

Metadata

  • Category badge
  • Read time estimate
  • Published date (optional)
  • Author (optional)

Performance

  • ✅ Lazy load thumbnails
  • ✅ Cache recommendations
  • ✅ Precompute scores (build time)
  • ✅ CDN для images

✅ Related Content Checklist

Implementation Checklist:

  • ☐ Clear section heading ("Related", "You May Like")
  • ☐ 3-6 recommended items
  • ☐ Thumbnail images (optimized)
  • ☐ Descriptive titles
  • ☐ Category/tag metadata visible
  • ☐ Hover effects (visual feedback)
  • ☐ Card-based clickable layout
  • ☐ Responsive (3 → 2 → 1 columns)
  • ☐ Algorithm selects relevant content
  • ☐ Falls back якщо no matches
  • ☐ Performance optimized (lazy loading)
  • ☐ Analytics tracking (click-through rate)