Розробка каталогу товарів для інтернет-магазину

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

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

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка каталогу товарів для інтернет-магазину
Середня
~1-2 тижні
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • 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

Розробка каталогу товарів для інтернет-магазину

Каталог — центральний модуль інтернет-магазину. Від його архітектури залежить всьо: швидкість пошуку, зручність навігації, SEO-трафік, простота управління асортиментом. Помилки в моделі даних каталогу — найдорожчі, тому що виправляються з міграцією існуючих даних та переробкою залежних модулів.

Ієрархія категорій

Дерево категорій зберігається у БД. Два розповсюджені підходи:

Adjacency List — кожна запис зберігає parent_id. Простота запису, але вибір усього дерева вимагає рекурсивного CTE:

WITH RECURSIVE category_tree AS (
  SELECT id, name, parent_id, 0 AS depth
  FROM categories WHERE parent_id IS NULL
  UNION ALL
  SELECT c.id, c.name, c.parent_id, ct.depth + 1
  FROM categories c
  JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree ORDER BY depth, name;

Nested Sets (MPPT) — кожна запись зберігає lft та rgt значення. Вибір поддерева: WHERE lft BETWEEN :parent_lft AND :parent_rgt — один запит без рекурсії. Запис складніший: при додаванні вузла оновлюють всі правих сусідів. Пакет kalnoy/nestedset для Laravel.

Closure Table — окрема таблиця всіх пар предок-нащадок. Найбільш гнучкий, займає більше місця. Для складних операцій з деревом (переміщення поддерев) оптимальний.

Рекомендація: для каталогів до 10 000 категорій Adjacency List з кешованим деревом у Redis — достатньо. MPPT — при частих виборках поддерев без кеша.

Модель атрибутів

Товари різних категорій мають різні набори атрибутів. Три підходи:

Таблиця з фіксованими колонками: products.color, products.size, products.weight. Працює тільки при однорідному асортименті. Додавання нового атрибуту — ALTER TABLE, міграція, деплой.

EAV (Entity-Attribute-Value):

attributes (id, name, type, unit, filterable, sortable, category_id)
product_attributes (product_id, attribute_id, value_text, value_numeric, value_boolean)

Гнучко, але повільно при JOIN-ах. Для фільтрації за атрибутами потрібен Elasticsearch або денормалізований індекс.

JSONB-колонка у PostgreSQL:

ALTER TABLE products ADD COLUMN attributes JSONB;
-- Індекс для конкретного атрибуту:
CREATE INDEX ON products ((attributes->>'color'));
-- GIN-індекс для будь-якого атрибуту:
CREATE INDEX ON products USING GIN (attributes);

Компромісний варіант: гнучкість EAV без надлишкових JOIN-ів. Підходить для каталогів до 500 000 товарів.

Варіанти товару (SKU)

Товар з варіантами (колір × розмір) — розповсюджена задача. Два паттерни:

Simple SKU: кожна комбінація — окрема запис у products. Просто, але складно управляти «батьківською» карточкою.

Parent-Child:

products (id, type, parent_id, sku, name, price, stock)
-- type: 'simple' | 'variable' | 'variant'
-- variant: parent_id → variable product

При відображенні карточки: завантажуємо батька + всі варіанти. Користувач вибирає комбінацію атрибутів → знаходимо відповідний варіант → оновлюємо ціну, фото, наявність.

Матриця варіантів для відображення вибору:

type VariantMatrix = {
  [attributeId: string]: {
    [value: string]: {
      variantId: number;
      inStock: boolean;
      price: number;
    }
  }
}

Структура URL та SEO

URL категорій — критичне для SEO. Три варіанти:

  • Плоский: /catalog/noutbuki — просто, втрачає контекст ієрархії
  • Ієрархічний: /catalog/elektronika/kompyutery/noutbuki — краще для SEO, складніше при переміщенні категорії
  • Гібридний: /noutbuki-c142 — читаний slug + унікальний ID (стійкий до переіменувань)

Для фільтрованих сторінок: /noutbuki?brand=apple&ram=16 з canonical на /noutbuki або окремі SEO-сторінки для популярних комбінацій (/noutbuki-apple-16gb як статична сторінка-агрегатор).

Schema.org: ItemList на сторінках категорій з ListItem для кожного товару в листингу.

Пагінація та нескінченна прокрутка

Offset-пагінація: LIMIT 48 OFFSET 144. Працює, але при глибоких сторінках (OFFSET 10000) PostgreSQL все равно читає 10048 рядків. Рішення — keyset pagination:

-- Замість OFFSET використовуємо курсор по останньому ID
SELECT * FROM products
WHERE (sort_value, id) > (:last_sort_value, :last_id)
ORDER BY sort_value, id
LIMIT 48;

Keyset pagination миттєва при будь-якій глибині, але не підтримує перехід на довільну сторінку.

Нескінченна прокрутка vs пагінація: для мобайлу — нескінченна прокрутка з IntersectionObserver, для десктопа з SEO-пріоритетом — класична пагінація (поисковики краще індексують сторінки з явними номерами).

Управління каталогом в CMS

Адміністративний інтерфейс каталогу:

  • Масове редагування: виділити 50 товарів → змінити категорію/статус/ціну
  • Імпорт з CSV/XLSX: маппинг колонок, попередпереглядом з помилками, фонове завантаження через queue
  • Drag-and-drop сортування категорій: візуальне дерево з можливістю перетягування
  • Управління атрибутами: додати атрибут у категорію → він з'являється на формах редагування всіх товарів категорії

Для масового імпорту: Laravel Jobs + Horizon. Файл завантажується в S3, завдання беруть з черги, парсяться рядок за рядком (через league/csv або PhpSpreadsheet), товари вставляються батчами по 100.

Кешування

Сторінки каталогу — основне навантаження на БД. Стратегія кешування:

Рівень Що кешуємо TTL
Redis Дерево категорій 1 година, інвалідація при змінені
Redis Листинг з фільтрами 5–15 хвилин
CDN (Cloudflare) HTML сторінок категорій 5 хвилин, stale-while-revalidate
Браузер Статика (зображення, JS, CSS) immutable

При змінені товара інвалідуємо кеш тільки тих сторінок, де він присутній. Cache tags у Laravel: Cache::tags(['category:electronics'])->flush().

Терміни

  • Базовий каталог (категорії, список товарів, карточка, пагінація): 2–3 тижні
  • З варіантами, EAV-атрибутами, імпортом та кешуванням: 4–7 тижнів
  • Інтеграція з Elasticsearch для пошуку та фільтрації додає 2–3 тижні