Розробка блоку "раніше переглянуті" 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка блоку "раніше переглянуті" 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

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

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

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

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка блоку "раніше переглянуті" 1С-Бітрікс

«Раніше переглянуті» — блок, який показує товари, які користувач відкривав у поточній або попередній сесії. Класичний інструмент утримання: користувач іде зі сторінки, потім повертається — і не шукає товар заново. Особливо цінний на мобільних пристроях, де історія браузера незручна.

Де зберігати історію переглядів

Варіант 1: localStorage (браузер). Максимально проста реалізація. JavaScript зберігає ID переглянутих товарів у localStorage. При завантаженні сторінки — читає список, відправляє AJAX-запит з ID, отримує актуальні дані про товари.

Плюси: працює без авторизації, без навантаження на сервер. Мінуси: історія не синхронізується між пристроями, зникає при очищенні браузера.

Варіант 2: Сервер (база даних). Для авторизованих користувачів історія зберігається на сервері. Анонімні — у localStorage або через b_sale_fuser (guestID).

Варіант 3: Гібридний. Анонімний користувач — localStorage + кеш на сервері по fuser_id. Після авторизації — історія мігрує в акаунт. Найбільш повноцінний варіант.

Реалізація через localStorage (швидкий варіант)

const STORAGE_KEY = 'viewed_products';
const MAX_ITEMS   = 20;

// Викликається при завантаженні картки товару
function trackProductView(productId) {
    let viewed = getViewedProducts();

    // Видаляємо якщо вже є (перемістимо на початок)
    viewed = viewed.filter(id => id !== productId);

    // Додаємо на початок
    viewed.unshift(productId);

    // Обмежуємо розмір
    if (viewed.length > MAX_ITEMS) {
        viewed = viewed.slice(0, MAX_ITEMS);
    }

    localStorage.setItem(STORAGE_KEY, JSON.stringify(viewed));
}

function getViewedProducts() {
    try {
        return JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
    } catch {
        return [];
    }
}

// Завантаження даних для блоку
function loadRecentlyViewed(currentProductId, containerId, limit = 8) {
    const viewed = getViewedProducts()
        .filter(id => id !== currentProductId)
        .slice(0, limit);

    if (viewed.length === 0) {
        document.getElementById(containerId).style.display = 'none';
        return;
    }

    fetch('/ajax/recently-viewed/', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({ ids: viewed }),
    })
    .then(r => r.json())
    .then(data => renderRecentlyViewed(data.products, containerId));
}

Серверний обробник AJAX

// local/ajax/recently-viewed/index.php
\Bitrix\Main\Loader::includeModule('iblock');
\Bitrix\Main\Loader::includeModule('catalog');

$ids = array_filter(array_map('intval', json_decode(file_get_contents('php://input'), true)['ids'] ?? []));

if (empty($ids) || count($ids) > 20) {
    echo json_encode(['products' => []]);
    exit;
}

// Зберігаємо порядок із localStorage
$result   = [];
$products = [];

$res = \CIBlockElement::GetList(
    [],
    ['ID' => $ids, 'IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y'],
    false,
    false,
    ['ID', 'NAME', 'DETAIL_PAGE_URL', 'PREVIEW_PICTURE']
);

while ($product = $res->GetNext()) {
    $productId = $product['ID'];
    $product['PRICE'] = \CPrice::GetBasePrice($productId);
    $products[$productId] = $product;
}

// Відновлюємо порядок переглядів
foreach ($ids as $id) {
    if (isset($products[$id])) {
        $result[] = $products[$id];
    }
}

header('Content-Type: application/json');
echo json_encode(['products' => $result]);

Серверне зберігання для авторизованих користувачів

CREATE TABLE custom_user_recently_viewed (
    id          SERIAL PRIMARY KEY,
    user_id     INT NOT NULL,
    product_id  INT NOT NULL,
    viewed_at   DATETIME DEFAULT NOW(),
    UNIQUE KEY uk_user_product (user_id, product_id),
    INDEX idx_user (user_id, viewed_at DESC)
);
// При авторизованому перегляді
if ($USER->IsAuthorized()) {
    $userId = $USER->GetID();
    // INSERT або UPDATE viewed_at
    Application::getConnection()->query("
        INSERT INTO custom_user_recently_viewed (user_id, product_id, viewed_at)
        VALUES ({$userId}, {$productId}, NOW())
        ON DUPLICATE KEY UPDATE viewed_at = NOW()
    ");

    // Обмежуємо історію 50 записами
    Application::getConnection()->query("
        DELETE FROM custom_user_recently_viewed
        WHERE user_id = {$userId}
        AND id NOT IN (
            SELECT id FROM (
                SELECT id FROM custom_user_recently_viewed
                WHERE user_id = {$userId}
                ORDER BY viewed_at DESC
                LIMIT 50
            ) t
        )
    ");
}

Міграція історії при авторизації

Коли анонімний користувач входить в акаунт, переносимо історію з localStorage у базу:

// При події успішної авторизації
document.addEventListener('userLoggedIn', function(e) {
    const viewed = getViewedProducts();
    if (viewed.length === 0) return;

    fetch('/ajax/sync-viewed-history/', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({ ids: viewed, user_id: e.detail.userId }),
    });
});

Відображення в особистому кабінеті

Розділ «Історія переглядів» в особистому кабінеті — повний список із можливістю очищення. Показуємо до 100 останніх товарів із пагінацією. Кнопка «Очистити історію» — DELETE з custom_user_recently_viewed по user_id + очищення localStorage.

Терміни

Етап Термін
localStorage-реалізація + AJAX-обробник 2–3 дні
Серверне зберігання для авторизованих 2–3 дні
Міграція історії при авторизації 1 день
Сторінка історії в особистому кабінеті 1–2 дні
Тестування (кросбраузер, мобайл) 1–2 дні

Разом: 1–1.5 тижні для повного варіанта. localStorage-only — 3–4 дні.