Розробка Smart-банерів з персоналізацією під кожного користувача
Ви витрачаєте бюджет на рекламні банери, але їх CTR не дотягує до 1%. Проблема в тому, що всі бачать одну й ту саму пропозицію. Ми вирішуємо це за допомогою smart-банерів: динамічних блоків, які показують кожному користувачеві саме ті товари, які він переглядав або які алгоритм вважає релевантними. Результат — зростання CTR у 2–3 рази та конверсії на 15–30%. Знижується і вартість залучення клієнта (CAC) на 20–30% за рахунок більш релевантного таргетингу. Замовте розробку smart-банерів — отримайте консультацію інженера для попередньої оцінки.
Як працює трекінг переглядів?
Персоналізація починається зі збору даних. Ми використовуємо JavaScript-клас ViewHistoryTracker, який зберігає історію переглядів у localStorage та синхронізує з сервером для авторизованих користувачів. Це мінімально інвазивне рішення — не вимагає cookie-банера та GDPR-згод для анонімних сесій.
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),
});
}
}
Що дає колаборативна фільтрація?
Простий показ останніх переглянутих товарів дає низький CTR — користувач уже бачив їх. Ми використовуємо ранжування з урахуванням ваг категорій та популярності, а також колаборативну фільтрацію для побудови матриці "користувач-товар". Нещодавні перегляди отримують більшу вагу, а дублі виключаються. Такий підхід збільшує CTR у 2–3 рази за нашими вимірами.
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);
}
Для великих проектів (від 10k товарів) виносимо двигун на сервер на PHP/Laravel з матрицею в PostgreSQL. Кешуємо рекомендації в Redis — час відповіді API не перевищує 50 мс.
Кейс: інтернет-магазин електроніки з каталогом 5000 товарів. Після впровадження smart-банера CTR виріс з 0,8% до 2,4%, конверсія з банера в покупку — 12%. Середній чек збільшився на 8% за рахунок крос-сейлів.
Порівняння підходів до реалізації
| Параметр | Клієнтський трекінг + серверний двигун | Зовнішня платформа (Retail Rocket) |
|---|---|---|
| Час впровадження | 3–5 днів | 1–2 дні |
| Точність рекомендацій | Висока (власні алгоритми) | Висока (ML-моделі) |
| Вартість обслуговування | Низька (свій сервер) | Щомісячна підписка |
| Контроль над даними | Повний | Частковий (передача даних) |
| Масштабованість | До 100k товарів | Від 10k до 1M+ товарів |
Порівняння алгоритмів рекомендацій
| Критерій | Клієнтське ранжування | Серверна колаборативна фільтрація |
|---|---|---|
| Дані | Історія в localStorage | Матриця покупок та переглядів |
| Точність | Середня | Висока |
| Завантаження сервера | Немає | Помірна (з кешем) |
| Холодний старт | Не проблема | Вимагає даних |
Типові помилки при впровадженні
- Показувати товари, які користувач щойно бачив. Завжди виключайте переглянуті позиції.
- Ігнорувати популярність товару — категорійна вага без урахування популярності дає слабкі рекомендації.
- Не кешувати серверні запити. Без Redis кожен перегляд генерує SQL-запит — при 10k користувачів БД ляже.
- Не відстежувати кліки по банеру. Без аналітики ви не дізнаєтесь реальний CTR.
- Забути про мобільну адаптацію — банер має коректно відображатися на всіх пристроях.
Як ми реалізуємо рендеринг smart-банера?
Компонент на React (або Vue) вбудовується в потрібне місце: sidebar, inline або sticky-bottom. Він запитує рекомендації через API та відображає товари з фото, назвою та ціною. При кліку відправляється подія в Google Analytics.
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,
});
}
Серверний ендпоінт рекомендацій
Ми використовуємо Laravel-контролер, який виключає переглянуті товари та ранжує за категорією та популярністю. Для прискорення запитів додаємо Redis-кеш.
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]);
}
}
Коли підключати зовнішні платформи?
Для магазинів з каталогом від 10k товарів або коли потрібна готова ML-модель, інтегруємо Retail Rocket або Mindbox. Базова інтеграція Retail Rocket займає 1-2 дні:
rrApi.view(123456);
rrApi.addToBasket(123456);
rrApiOnReady(function() {
rrApi.recommend('block_id_from_rr_panel', {
callback: function(items) { renderRecommendations(items); }
});
});
Що входить в роботу?
- Проектування схеми трекінгу та зберігання даних
- Розробка клієнтського компонента банера з підтримкою різних placement
- Серверний ендпоінт рекомендацій з кешуванням
- Інтеграція з аналітикою (GA/Яндекс.Метрика)
- Документація API та інструкція з вбудовування
- Передача доступів до репозиторію та хостингу
- Навчання вашого розробника (1 година онлайн)
- Гарантія 3 місяці на коректну роботу алгоритмів
Терміни та вартість
Терміни реалізації: від 3 до 8 днів залежно від складності. Вартість розраховується індивідуально — оцінимо проект після брифу. За час роботи ми реалізували smart-банери для десятків інтернет-магазинів, середній ріст CTR склав 180%. Наша команда має 5+ років досвіду в e-commerce персоналізації.
Якщо ви хочете збільшити конверсію з рекламних блоків без зайвих витрат, зв'яжіться з нами — обговоримо вашу задачу та запропонуємо оптимальне рішення. Отримайте консультацію інженера для попередньої оцінки.







