Функционал избранного в интернет-магазине: повышаем конверсию
Для кого эта статья:
- Веб-разработчики, интересующиеся функционалом интернет-магазинов
- Специалисты по электронной коммерции, стремящиеся улучшить конверсию своих сайтов
Студенты и начинающие специалисты, обучающиеся веб-разработке и проектированию интерфейсов
Кнопка "Добавить в избранное" – та маленькая деталь интерфейса, которая может увеличить конверсию магазина на 15-20%. Когда пользователь откладывает товар в закладки, вероятность его возвращения к покупке возрастает в три раза. Но как правильно интегрировать эту функцию? Перед вами пошаговое руководство по внедрению Wish list на ваш e-commerce сайт — от проектирования архитектуры до готовой имплементации с примерами кода и рабочими решениями. 🛒
Хотите стать специалистом, который сможет самостоятельно создавать функционал избранных товаров и другие важные элементы современных интернет-магазинов? Профессия Веб-разработчик от Skypro даст вам все необходимые навыки — от создания интерактивных интерфейсов до работы с базами данных и API. Вы научитесь не просто копировать код, а создавать элегантные и эффективные решения, которые будут востребованы на рынке. Станьте разработчиком, который знает, как превращать идеи в работающий продукт!
Реализация функции избранного на сайте: что нужно знать
Функционал избранных товаров (или Wish list) — критически важный элемент современного интернет-магазина. По данным аналитики, пользователи, использующие "избранное", тратят на 37% больше времени на сайте и с вероятностью в 2,5 раза выше совершают покупку.
Прежде чем приступить к реализации, важно понимать компоненты этой системы:
- Клиентская часть — элементы интерфейса (кнопки, иконки, список отложенных товаров)
- Серверная логика — механизм хранения и управления списками избранных товаров
- Система аутентификации — определяет, как будут храниться данные (локально или в профиле)
- Интеграция — взаимосвязь функционала с другими элементами магазина
Существует два базовых подхода к реализации:
| Подход | Преимущества | Недостатки | Использование |
|---|---|---|---|
| Хранение на стороне клиента (localStorage) | Быстрая работа, не требует авторизации | Данные привязаны к устройству, ограниченный объем | Для небольших магазинов, быстрого запуска |
| Хранение на сервере (БД) | Синхронизация между устройствами, постоянное хранение | Требует авторизации, сложнее в реализации | Для средних и крупных магазинов |
Алексей Корнилов, Senior Frontend Developer На одном из проектов мы изначально реализовали "избранное" только через localStorage. Всё работало быстро, но клиенты стали жаловаться: "Почему мои избранные товары не сохраняются, когда я перехожу с телефона на компьютер?". Пришлось срочно переделывать архитектуру, добавляя серверное хранение. Мы потеряли на этом две недели разработки. Теперь я всегда советую сразу планировать гибридный подход: для неавторизованных пользователей — localStorage, а после авторизации — синхронизация с сервером. Это сэкономит вам массу времени в будущем.
Ключевые метрики, на которые влияет правильная реализация избранного:
- Увеличение среднего времени сеанса на 25-40%
- Рост повторных визитов на сайт до 30%
- Повышение конверсии за счет отложенных покупок на 15-20%
- Улучшение пользовательского опыта (UX) и увеличение лояльности
Перед началом разработки необходимо определить, какие данные о товаре будут сохраняться в списке избранного. Минимальный набор включает: ID товара, название, цена, URL изображения и ссылка на страницу товара. 🔍

Проектирование архитектуры для избранных товаров
Архитектура системы "избранное" должна быть тщательно спроектирована, чтобы обеспечить как удобство для пользователя, так и масштабируемость решения. Рассмотрим ключевые компоненты архитектуры:
Грамотно спроектированная архитектура — основа надежного функционала избранных товаров. От этого зависит не только быстродействие, но и возможность дальнейшего масштабирования системы.
Базовая модель данных для хранения избранных товаров в базе данных:
CREATE TABLE favorites (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
product_id INT NOT NULL,
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY user_product (user_id, product_id),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE
);
Эта структура позволяет эффективно хранить связи между пользователями и товарами, которые они добавили в избранное. Уникальный ключ предотвращает дублирование записей.
Существует несколько архитектурных паттернов для реализации функционала избранного:
- Однотабличная модель — все избранные товары хранятся в одной таблице (подходит для небольших и средних проектов)
- Многотабличная модель — разделение данных на несколько таблиц (для крупных проектов с высокой нагрузкой)
- Гибридная модель — комбинирует локальное хранение и синхронизацию с сервером
Для обеспечения высокой производительности рекомендуется использовать индексирование базы данных по ключевым полям: userid и productid. Это значительно ускорит выборку при больших объемах данных.
| Архитектурный паттерн | Сложность реализации | Производительность | Масштабируемость |
|---|---|---|---|
| Однотабличная модель | Низкая | Высокая для малых объемов | Ограниченная |
| Многотабличная модель | Высокая | Средняя с потенциалом роста | Высокая |
| Гибридная модель | Средняя | Высокая | Средняя |
При проектировании API для взаимодействия с избранным, следует придерживаться RESTful принципов:
GET /api/favorites— получение списка избранных товаров пользователяPOST /api/favorites— добавление товара в избранноеDELETE /api/favorites/{product_id}— удаление товара из избранного
Важно также продумать механизм миграции данных для неавторизованных пользователей. Когда пользователь авторизуется, его локально сохраненные избранные товары должны автоматически перенестись в его профиль. 📊
Добавление избранного на сайт интернет-магазина: код и логика
Переходим к практической реализации функционала избранных товаров. Для начала реализуем клиентскую часть с использованием JavaScript.
Базовый HTML-шаблон для кнопки "Добавить в избранное":
<button class="favorite-btn" data-product-id="123" data-product-name="Смартфон Galaxy S21" data-product-price="54990">
<i class="fa fa-heart"></i> В избранное
</button>
JavaScript-код для обработки действий с избранным (используя localStorage для неавторизованных пользователей):
// Модуль для работы с избранными товарами
const Favorites = {
// Получение списка избранных товаров
getItems() {
const items = localStorage.getItem('favorites');
return items ? JSON.parse(items) : [];
},
// Добавление товара в избранное
addItem(product) {
const favorites = this.getItems();
// Проверка на дублирование
if (!favorites.some(item => item.id === product.id)) {
favorites.push(product);
localStorage.setItem('favorites', JSON.stringify(favorites));
this.updateCounter();
return true;
}
return false;
},
// Удаление товара из избранного
removeItem(productId) {
let favorites = this.getItems();
favorites = favorites.filter(item => item.id !== productId);
localStorage.setItem('favorites', JSON.stringify(favorites));
this.updateCounter();
},
// Проверка наличия товара в избранном
isInFavorites(productId) {
return this.getItems().some(item => item.id === productId);
},
// Обновление счетчика избранных товаров
updateCounter() {
const counter = document.querySelector('.favorites-counter');
if (counter) {
counter.textContent = this.getItems().length;
}
}
};
// Инициализация обработчиков событий
document.addEventListener('DOMContentLoaded', function() {
// Обновляем счетчик при загрузке страницы
Favorites.updateCounter();
// Обрабатываем клики по кнопкам "В избранное"
document.querySelectorAll('.favorite-btn').forEach(button => {
const productId = button.dataset.productId;
// Устанавливаем начальное состояние кнопки
if (Favorites.isInFavorites(productId)) {
button.classList.add('active');
}
button.addEventListener('click', function(e) {
e.preventDefault();
const product = {
id: this.dataset.productId,
name: this.dataset.productName,
price: this.dataset.productPrice,
image: this.dataset.productImage || '',
url: this.dataset.productUrl || window.location.href
};
if (Favorites.isInFavorites(product.id)) {
Favorites.removeItem(product.id);
this.classList.remove('active');
} else {
Favorites.addItem(product);
this.classList.add('active');
}
});
});
});
Для авторизованных пользователей требуется взаимодействие с сервером. Пример AJAX-запросов для работы с API:
// Функция добавления в избранное для авторизованных пользователей
function addToFavoritesAuth(productId) {
return fetch('/api/favorites', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({ product_id: productId })
})
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
});
}
// Функция удаления из избранного
function removeFromFavoritesAuth(productId) {
return fetch(`/api/favorites/${productId}`, {
method: 'DELETE',
headers: {
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
}
})
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
});
}
Важно также продумать визуальную обратную связь. Пользователь должен четко видеть, что товар добавлен в избранное. Для этого можно использовать CSS-анимацию:
.favorite-btn {
transition: all 0.3s ease;
color: #999;
}
.favorite-btn.active {
color: #ff3e3e;
transform: scale(1.1);
}
.favorite-btn.active i {
animation: heartbeat 1s ease-in-out;
}
@keyframes heartbeat {
0% { transform: scale(1); }
25% { transform: scale(1.2); }
50% { transform: scale(1); }
75% { transform: scale(1.2); }
100% { transform: scale(1); }
}
Не забудьте реализовать страницу со списком избранных товаров. Базовая структура такой страницы:
<div class="favorites-list">
<h1>Избранные товары</h1>
<div class="favorites-items" id="favorites-container">
<!-- Здесь будут отображаться избранные товары -->
</div>
<script>
// Загружаем и отображаем избранные товары
document.addEventListener('DOMContentLoaded', function() {
const container = document.getElementById('favorites-container');
const favorites = Favorites.getItems();
if (favorites.length === 0) {
container.innerHTML = '<p>У вас пока нет избранных товаров</p>';
return;
}
favorites.forEach(product => {
const productHtml = `
<div class="product-card">
<img src="${product.image}" alt="${product.name}">
<h3>${product.name}</h3>
<p class="price">${product.price} ₽</p>
<div class="actions">
<a href="${product.url}" class="btn btn-primary">Посмотреть</a>
<button class="btn btn-danger remove-favorite" data-product-id="${product.id}">Удалить</button>
</div>
</div>
`;
container.insertAdjacentHTML('beforeend', productHtml);
});
// Обработка удаления товаров из списка
document.querySelectorAll('.remove-favorite').forEach(button => {
button.addEventListener('click', function() {
const productId = this.dataset.productId;
Favorites.removeItem(productId);
this.closest('.product-card').remove();
if (document.querySelectorAll('.product-card').length === 0) {
container.innerHTML = '<p>У вас пока нет избранных товаров</p>';
}
});
});
});
</script>
</div>
Правильная реализация избранного существенно повышает удобство использования магазина. По статистике, добавление этой функции может увеличить конверсию на 7-12% за счет возврата пользователей к отложенным товарам. 🔄
Работа с пользовательскими данными при сохранении избранного
Корректная работа с пользовательскими данными — критически важный аспект функционала избранных товаров. Необходимо обеспечить не только удобство использования, но и безопасность информации.
Марина Светлова, UX-исследователь Мы проводили A/B-тестирование двух версий функционала избранного для крупного интернет-магазина одежды. В первом варианте мы требовали обязательной регистрации для сохранения товаров, во втором — разрешали сохранять анонимно с предложением зарегистрироваться позже. Результаты оказались впечатляющими: во втором случае на 78% больше пользователей начали использовать функцию "избранное" и, что самое интересное, конверсия в регистрацию выросла на 42%! Люди гораздо охотнее создавали аккаунт, когда уже накопили "ценность" в виде списка любимых товаров, которую боялись потерять. Это убедило меня, что лучшая стратегия — сначала дать пользователю создать ценность, а затем предложить её сохранить через регистрацию.
Рассмотрим основные сценарии работы с данными пользователей:
Для неавторизованных пользователей:
Когда пользователь не авторизован, данные о его избранных товарах хранятся локально в браузере. Реализуем механизм хранения с помощью localStorage:
// Сохранение данных в localStorage
function saveToLocalStorage(productId) {
let favorites = JSON.parse(localStorage.getItem('favorites') || '[]');
if (!favorites.includes(productId)) {
favorites.push(productId);
localStorage.setItem('favorites', JSON.stringify(favorites));
}
}
// Получение данных из localStorage
function getLocalFavorites() {
return JSON.parse(localStorage.getItem('favorites') || '[]');
}
При авторизации пользователя необходимо синхронизировать локальные данные с серверными:
// Синхронизация после авторизации
function syncFavoritesAfterLogin(userId) {
const localFavorites = getLocalFavorites();
if (localFavorites.length > 0) {
// Отправляем локальные избранные на сервер
fetch('/api/favorites/sync', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({
user_id: userId,
favorites: localFavorites
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Очищаем локальное хранилище после успешной синхронизации
localStorage.removeItem('favorites');
}
});
}
}
Для авторизованных пользователей информация о избранных товарах должна сохраняться в базе данных. Схема базы данных может выглядеть так:
- users — таблица пользователей
- products — таблица товаров
- favorites — таблица связей между пользователями и избранными товарами
Примеры серверных запросов для работы с избранными товарами (на примере PHP/Laravel):
// Добавление товара в избранное
public function addToFavorites(Request $request)
{
$user = Auth::user();
$productId = $request->input('product_id');
// Проверяем, не добавлен ли уже этот товар
if (!$user->favorites()->where('product_id', $productId)->exists()) {
$user->favorites()->attach($productId);
return response()->json(['success' => true]);
}
return response()->json(['success' => false, 'message' => 'Товар уже в избранном']);
}
// Получение списка избранных товаров
public function getFavorites()
{
$user = Auth::user();
$favorites = $user->favorites()->with(['images', 'category'])->get();
return response()->json($favorites);
}
// Удаление товара из избранного
public function removeFromFavorites(Request $request, $productId)
{
$user = Auth::user();
$user->favorites()->detach($productId);
return response()->json(['success' => true]);
}
// Синхронизация локальных избранных с сервером
public function syncFavorites(Request $request)
{
$user = Auth::user();
$localFavorites = $request->input('favorites');
foreach ($localFavorites as $productId) {
if (!$user->favorites()->where('product_id', $productId)->exists()) {
$user->favorites()->attach($productId);
}
}
return response()->json(['success' => true]);
}
Важно обеспечить безопасность данных пользователя. Рекомендуется:
- Использовать HTTPS для защиты передаваемых данных
- Проверять права доступа пользователя к операциям с избранным
- Валидировать все входящие данные на сервере
- Защищать от CSRF-атак
При работе с большими объемами данных рекомендуется использовать пагинацию для списка избранных товаров:
// Получение избранных товаров с пагинацией
public function getPaginatedFavorites(Request $request)
{
$user = Auth::user();
$perPage = $request->input('per_page', 10);
$favorites = $user->favorites()
->with(['images', 'category'])
->paginate($perPage);
return response()->json($favorites);
}
Грамотная стратегия работы с данными пользователей обеспечивает не только бесперебойную работу функционала, но и повышает лояльность клиентов к вашему интернет-магазину. 🔐
Готовые решения для избранного в популярных CMS
Не всегда требуется разрабатывать функционал избранных товаров с нуля. Большинство популярных CMS предлагают готовые решения, которые можно легко интегрировать в ваш интернет-магазин.
Сравним доступные решения для наиболее популярных CMS для электронной коммерции:
| CMS | Плагин/Модуль | Стоимость | Возможности | Сложность настройки |
|---|---|---|---|---|
| WordPress (WooCommerce) | YITH WooCommerce Wishlist | Бесплатно (базовый) / $89.99 (премиум) | Создание нескольких списков, шаринг, уведомления о наличии | Низкая |
| OpenCart | Wishlist Module | Встроенный | Базовая функциональность добавления в избранное | Низкая |
| Magento 2 | Wishlist (встроенный) | Встроенный | Полная интеграция с экосистемой, несколько списков, шаринг | Средняя |
| Shopify | Wishlist Plus | от $14.99/мес | Автоматическая синхронизация, аналитика, рассылки | Низкая |
| 1С-Битрикс | Компонент "Избранные товары" | Встроенный | Полная интеграция с каталогом, корзиной и пользователями | Средняя |
Рассмотрим пошаговую интеграцию решения для наиболее популярных систем:
WordPress (WooCommerce) с YITH WooCommerce Wishlist:
- Установите плагин YITH WooCommerce Wishlist через панель управления WordPress (Плагины > Добавить новый > найдите "YITH WooCommerce Wishlist" > Установить > Активировать)
- Перейдите в настройки плагина: WooCommerce > YITH Plugins > Wishlist
- Настройте основные параметры: расположение кнопки, текст, стили и т.д.
- Добавьте шорткод
[yith_wcwl_wishlist]на страницу, где хотите отображать список избранного - Опционально: настройте уведомления по email и другие расширенные функции в премиум-версии
OpenCart:
- Функционал избранного встроен в OpenCart и доступен "из коробки"
- Для настройки перейдите в Система > Настройки > Редактировать свой магазин
- Убедитесь, что опция "Разрешить списки желаний" включена
- Кнопка "Добавить в избранное" будет автоматически отображаться на страницах товаров
- Для расширения функциональности можно установить дополнительные модули из маркетплейса OpenCart
1С-Битрикс:
- В стандартной редакции "Управление сайтом" компонент "Избранные товары" уже встроен
- Перейдите в режим редактирования страницы, где хотите разместить список избранных товаров
- Добавьте компонент "Каталог > Избранные товары"
- Настройте параметры отображения в визуальном редакторе
- Настройте права доступа к функционалу избранного в административной панели
Magento 2:
- Функционал Wishlist встроен в Magento 2 по умолчанию
- Для настройки перейдите в Stores > Configuration > Customers > Wish List
- Включите или отключите функции: возможность делиться списками, добавление комментариев и т.д.
- Настройте отображение кнопки в Stores > Configuration > Catalog > Catalog
- Для расширения функциональности можно установить дополнительные расширения из Magento Marketplace
Преимущества использования готовых решений:
- Быстрая интеграция без необходимости писать собственный код
- Регулярные обновления и исправления безопасности
- Совместимость с другими модулями и обновлениями CMS
- Документация и сообщество пользователей для решения проблем
- Часто включает дополнительный функционал, такой как шаринг списков или уведомления
Недостатки готовых решений:
- Ограниченные возможности кастомизации (особенно в бесплатных версиях)
- Потенциальные конфликты с другими установленными плагинами
- Дополнительная нагрузка на сервер от "тяжелых" плагинов
- Зависимость от разработчика плагина для обновлений и поддержки
При выборе готового решения обратите внимание на частоту обновлений, количество активных установок и отзывы пользователей. Качественное готовое решение может значительно сократить время разработки и обеспечить стабильную работу функционала избранных товаров. 🛠️
Реализация функционала избранных товаров — это инвестиция в пользовательский опыт, которая окупается повышенной вовлеченностью и ростом конверсии. Независимо от выбранного подхода — будь то собственное решение с нуля или интеграция готового плагина — ключевыми факторами успеха станут надежное хранение данных, интуитивный интерфейс и бесшовный пользовательский опыт. Помните, что лучшее решение — то, которое позволяет начать с простой реализации и постепенно наращивать функциональность, ориентируясь на реальное поведение пользователей и аналитику.