Реалізація персоналізації контенту по сегментах аудиторії на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація персоналізації контенту по сегментах аудиторії на сайті
Складна
~5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація персоналізації контенту за сегментами аудиторії

Персоналізація — це показ різного контенту різним сегментам користувачів для підвищення релевантності та конверсії. На відміну від A/B-тестування (випадковий розподіл), персоналізація є детерміністичною: користувачі з певними атрибутами завжди бачать відповідний контент.

Типи сегментів

  • Поведінкові: переглянуті товари, категорії, попередні покупки
  • Демографічні: гео, мова, пристрій
  • Джерело трафіку: Google Ads, SEO, email, прямий
  • Стадія воронки: новий відвідувач, повернення, зареєстрований, платіж
  • Бізнес-атрибути: тариф, компанія, роль

Архітектура персоналізації

User Request
     ↓
Segment Resolver (хто цей користувач?)
     ↓
Rule Engine (який контент показати?)
     ↓
Content Renderer (відрендерити персоналізований варіант)
     ↓
Analytics (зафіксувати показ + конверсію)

Серверна сегментація

# segment_resolver.py
class SegmentResolver:
    def resolve(self, user: User, request: Request) -> list[str]:
        segments = []

        # Геолокація
        country = get_geoip(request.remote_addr)
        segments.append(f"country:{country}")

        # Пристрій
        device = parse_device(request.user_agent)
        segments.append(f"device:{device}")

        # Джерело трафіку
        referrer = request.referrer or ''
        if 'google' in referrer:
            segments.append("source:google")
        elif 'email' in request.args.get('utm_medium', ''):
            segments.append("source:email")
        else:
            segments.append("source:direct")

        # Стадія життєвого циклу
        if not user:
            segments.append("lifecycle:anonymous")
        elif not user.has_purchases:
            segments.append("lifecycle:prospect")
            if user.session_count > 3:
                segments.append("lifecycle:warm_lead")
        else:
            segments.append("lifecycle:customer")
            segments.append(f"plan:{user.plan}")

        # Поведінкові (з Redis)
        viewed_cats = redis.smembers(f"viewed_cats:{user.id}")
        for cat in viewed_cats:
            segments.append(f"interest:{cat}")

        return segments

Rule Engine для маплення сегментів на контент

# personalization_rules.py
RULES = [
    {
        'id': 'email_promo_banner',
        'segments': ['source:email'],
        'content': {
            'hero_banner': 'Ваш эксклюзивний промокод: EMAIL20',
            'cta_text': 'Отримати знижку 20%'
        },
        'priority': 100
    },
    {
        'id': 'warm_lead_urgency',
        'segments': ['lifecycle:warm_lead'],
        'content': {
            'hero_banner': 'Ви переглядали {last_viewed_product} — залишилось 3 шт',
            'floating_badge': 'Ваш кошик чекає'
        },
        'priority': 90
    },
    {
        'id': 'customer_cross_sell',
        'segments': ['lifecycle:customer'],
        'content': {
            'sidebar': 'recommended_for_customers',
            'hero_banner': 'З повертенням! Новинки для вас:'
        },
        'priority': 80
    },
    {
        'id': 'mobile_simplified',
        'segments': ['device:mobile'],
        'content': {
            'layout': 'mobile_first',
            'show_phone_cta': True
        },
        'priority': 50
    }
]

def get_personalized_content(segments: list[str]) -> dict:
    matched = []
    for rule in sorted(RULES, key=lambda r: r['priority'], reverse=True):
        if all(s in segments for s in rule['segments']):
            matched.append(rule)
            break  # Застосуйте тільки перше підходяще правило

    if not matched:
        return get_default_content()

    return matched[0]['content']

Frontend реалізація з персоналізованими слотами

// PersonalizationSlot.jsx
function PersonalizationSlot({ slotId, fallback }) {
  const [content, setContent] = useState(null)
  const { segments } = useUserSegments()

  useEffect(() => {
    fetch('/api/personalization', {
      method: 'POST',
      body: JSON.stringify({ slot: slotId, segments })
    })
      .then(r => r.json())
      .then(setContent)
  }, [slotId, segments])

  if (!content) return fallback || null
  return <div dangerouslySetInnerHTML={{ __html: content.html }} />
}

// Використання
function HeroSection() {
  return (
    <section>
      <PersonalizationSlot
        slotId="hero_banner"
        fallback={<DefaultHeroBanner />}
      />
    </section>
  )
}

Edge персоналізація (без затримки)

// Cloudflare Worker: персоналізувати HTML на Edge
addEventListener('fetch', event => {
  event.respondWith(personalizeResponse(event.request))
})

async function personalizeResponse(request) {
  const response = await fetch(request)
  if (!response.headers.get('Content-Type')?.includes('text/html')) {
    return response
  }

  const segments = getSegmentsFromCookies(request)
  const content = getPersonalizedContent(segments)

  const html = await response.text()
  const personalized = html
    .replace('{{hero_headline}}', content.hero_headline)
    .replace('{{cta_text}}', content.cta_text)

  return new Response(personalized, {
    headers: response.headers,
    status: response.status
  })
}

Рекомендаційний механізм

# Collaborative filtering для рекомендацій товарів
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

def get_recommendations(user_id, all_purchases, n=5):
    # Матриця користувач × товар
    users = list(all_purchases.keys())
    items = list(set(item for purchases in all_purchases.values() for item in purchases))

    matrix = np.zeros((len(users), len(items)))
    for i, user in enumerate(users):
        for item in all_purchases.get(user, []):
            j = items.index(item)
            matrix[i][j] = 1

    # Схожість користувачів
    user_idx = users.index(user_id)
    similarities = cosine_similarity(matrix[user_idx:user_idx+1], matrix)[0]

    # Зважені рекомендації
    scores = similarities @ matrix
    scores[0][list(all_purchases.get(user_id, {}))] = 0  # виключити вже куплені

    top_indices = scores[0].argsort()[-n:][::-1]
    return [items[i] for i in top_indices]

Вимірювання впливу персоналізації

def measure_personalization_impact(analytics_db):
    # Порівняти конверсію: персоналізований контент vs типовий
    results = analytics_db.query("""
        SELECT
            is_personalized,
            COUNT(DISTINCT session_id) AS sessions,
            SUM(converted) AS conversions,
            ROUND(AVG(CAST(converted AS FLOAT)) * 100, 2) AS cvr,
            ROUND(AVG(order_value), 0) AS avg_order_value
        FROM sessions
        WHERE date >= CURRENT_DATE - INTERVAL '30 days'
        GROUP BY is_personalized
    """)
    return results

Час виконання

Реалізація системи персоналізації з сегментацією, Rule Engine та вимірюванням впливу — 5–10 робочих днів.