Реализация Smart-баннеров (персонализированная реклама) на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

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

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация Smart-баннеров (персонализированная реклама) на сайте
Средняя
~3-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

Реализация Smart-баннеров (персонализированная реклама) на сайте

Smart-баннеры — это рекламные блоки, содержимое которых генерируется динамически на основе поведения пользователя, истории просмотров и данных из продуктового каталога. В отличие от статических баннеров, они показывают именно те товары или услуги, которые пользователь уже просматривал или которые алгоритм предсказывает как релевантные.

Механика работы

Система состоит из трёх частей: слежение за просмотрами, движок рекомендаций и рендеринг баннера. Данные о просмотренных товарах накапливаются в браузере и/или на сервере, движок ранжирует позиции, баннер собирается из шаблона.

Трекинг просмотров

class ViewHistoryTracker {
  private readonly KEY = 'view_history';
  private readonly MAX_ITEMS = 50;

  track(item: ViewedItem): void {
    const history = this.get();

    // Убираем дублирующийся элемент, добавляем в начало
    const filtered = history.filter(i => i.id !== item.id);
    const updated = [
      { ...item, viewed_at: Date.now() },
      ...filtered,
    ].slice(0, this.MAX_ITEMS);

    localStorage.setItem(this.KEY, JSON.stringify(updated));
    this.syncToServer(item); // асинхронно
  }

  get(): ViewedItem[] {
    try {
      return JSON.parse(localStorage.getItem(this.KEY) ?? '[]');
    } catch {
      return [];
    }
  }

  getRecent(count = 10): ViewedItem[] {
    return this.get().slice(0, count);
  }

  private async syncToServer(item: ViewedItem): Promise<void> {
    if (!getAuthToken()) return; // синхронизируем только для авторизованных
    await fetch('/api/views', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(item),
    });
  }
}

// Пример вызова на странице товара
const tracker = new ViewHistoryTracker();
tracker.track({
  id: '123',
  type: 'product',
  category: 'laptops',
  price: 89900,
  title: 'MacBook Pro 14',
  image: '/images/mbp14.jpg',
  url: '/catalog/laptops/macbook-pro-14',
});

Движок рекомендаций

Базовый алгоритм — коллаборативная фильтрация на основе истории просмотров с учётом весов (недавние просмотры весят больше):

function rankItems(
  history: ViewedItem[],
  candidates: CatalogItem[]
): CatalogItem[] {
  const categoryWeights: Record<string, number> = {};
  const viewedIds = new Set(history.map(i => i.id));

  // Считаем веса категорий из истории просмотров
  history.forEach((item, index) => {
    const recencyWeight = 1 / (index + 1); // первые просмотры важнее
    categoryWeights[item.category] = (categoryWeights[item.category] ?? 0) + recencyWeight;
  });

  return candidates
    .filter(c => !viewedIds.has(c.id)) // убираем уже просмотренные
    .map(candidate => ({
      ...candidate,
      score: (categoryWeights[candidate.category] ?? 0) * (candidate.popularity ?? 1),
    }))
    .sort((a, b) => b.score - a.score)
    .slice(0, 6);
}

Для серьёзных проектов движок выносится на сервер — PHP/Python — и использует матрицу пользователь×товар.

Рендеринг Smart-баннера

interface SmartBannerProps {
  placement: 'sidebar' | 'inline' | 'sticky-bottom';
  title?: string;
}

function SmartBanner({ placement, title = 'Вы смотрели' }: SmartBannerProps) {
  const [items, setItems] = useState<CatalogItem[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const history = tracker.getRecent();
    if (history.length === 0) {
      setLoading(false);
      return;
    }

    fetch('/api/recommendations', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        viewed_ids: history.map(i => i.id),
        categories: [...new Set(history.map(i => i.category))],
        limit: placement === 'sidebar' ? 4 : 6,
      }),
    })
      .then(r => r.json())
      .then(data => setItems(data.items))
      .finally(() => setLoading(false));
  }, [placement]);

  if (loading) return <BannerSkeleton count={4} />;
  if (items.length === 0) return null; // не показываем пустой баннер

  return (
    <div className={`smart-banner smart-banner--${placement}`}>
      <h3 className="smart-banner__title">{title}</h3>
      <div className="smart-banner__grid">
        {items.map(item => (
          <a
            key={item.id}
            href={item.url}
            className="smart-banner__item"
            onClick={() => trackBannerClick(item, placement)}
          >
            <img src={item.image} alt={item.title} loading="lazy" />
            <span className="smart-banner__name">{item.title}</span>
            <span className="smart-banner__price">{formatPrice(item.price)}</span>
          </a>
        ))}
      </div>
    </div>
  );
}

function trackBannerClick(item: CatalogItem, placement: string): void {
  gtag('event', 'smart_banner_click', {
    item_id: item.id,
    item_name: item.title,
    placement,
    item_category: item.category,
  });
}

Серверный эндпоинт рекомендаций

// RecommendationsController.php
class RecommendationsController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $viewedIds = $request->input('viewed_ids', []);
        $categories = $request->input('categories', []);
        $limit = min($request->input('limit', 6), 12);

        $items = Product::query()
            ->whereNotIn('id', $viewedIds)
            ->where('is_active', true)
            ->where(function ($q) use ($categories) {
                $q->whereIn('category_slug', $categories)
                  ->orWhere('is_bestseller', true);
            })
            ->orderByRaw('
                CASE WHEN category_slug = ANY(?) THEN 1 ELSE 2 END,
                popularity DESC
            ', ['{' . implode(',', $categories) . '}'])
            ->limit($limit)
            ->get(['id', 'title', 'price', 'image', 'url', 'category_slug']);

        return response()->json(['items' => $items]);
    }
}

Персонализация через внешние платформы

Для e-commerce с большим каталогом (10k+ товаров) стоит рассмотреть специализированные движки:

  • Retail Rocket — российский сервис персонализации, интегрируется через JS-пиксель
  • Mindbox — CDP с модулем рекомендаций, API-интеграция
  • Dynamic Yield — enterprise-решение с ML-рекомендациями

Базовая интеграция Retail Rocket:

// Трекинг просмотра товара
rrApi.view(123456); // ID товара в системе Retail Rocket

// Трекинг добавления в корзину
rrApi.addToBasket(123456);

// Блок рекомендаций рендерится через callback
rrApiOnReady(function() {
  rrApi.recommend('block_id_from_rr_panel', {
    callback: function(items) {
      renderRecommendations(items);
    }
  });
});

Сроки

Собственная реализация трекинга + движка рекомендаций + баннер-компонент: 3–5 дней. Интеграция с Retail Rocket или аналогом: 1–2 дня. Серверный движок рекомендаций с матрицей на PostgreSQL: 3–5 дней.