Розробка системи керування меню сайту під ключ

Кожна зміна меню на сайті перетворюється на задачу для розробника та гальмує випуск оновлень. Ми розробляємо систему управління меню, яка дозволяє менеджерам самостійно редагувати структуру через зручний drag-and-drop інтерфейс. Наша команда реалізує проєкт під ключ — від моделі даних до кешування та мультимовності, забезпечуючи стабільну роботу та подальшу підтримку.

Розробка та обслуговування будь-яких видів сайтів:

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка системи керування меню сайту під ключ
Середній
~2-3 дні
Часті запитання

Менеджери регулярно просять додати новий пункт у меню — кожен запит перетворюється на задачу для розробника, гальмує релізи та відволікає команду від основного функціоналу. Ми спроєктували систему керування меню, яка вирішує цю проблему: правки вносяться за хвилини без залучення програмістів. За 10+ років ми впровадили такі системи для проектів з каталогами до 50 000 товарів та мультиязичними сайтами на 12 мов. Одне з таких рішень — власна система керування навігацією, яка окупається в середньому за 2 місяці за рахунок скорочення часу розробників.

Які проблеми вирішує система керування меню?

Проблема 1: ручне правлення коду при кожній зміні. Без спеціального інструменту будь-який новий пункт вимагає редагування шаблонів, деплою, а іноді й узгодження з бекендом. Наша система дає менеджерам drag-and-drop інтерфейс, де зміна структури меню займає 1 хвилину. Економія бюджету на підтримку сягає 60%.

Проблема 2: повільне завантаження меню з великою вкладеністю. Стандартний підхід з рекурсивними запитами до БД дає N+1 запитів — для 500 пунктів це 250 мс завантаження. Ми використовуємо eager loading та кеш, знижуючи час до 2 мс. Навіть для 10 000 пунктів меню віддається за 5 мс.

Як влаштована модель даних? — розробка системи керування

Модель даних будується на двох таблицях: menus та menu_items. Таблиця menus містить записи для кожного меню (головне, футер, мобільне). Поле locale дозволяє створювати окремі структури для кожної мови. Таблиця menu_items зберігає ієрархію пунктів з типом, порядком та посиланням. Вкладеність реалізована через parent_id та order. При зміні порядку пунктів ми перераховуємо order лише зачеплені записи — інкрементальне оновлення.

Тип пункту Опис
link Довільний URL, вводиться вручну
page Вибір зі списку сторінок CMS
category Вибір категорії каталогу
custom Якірне посилання (#section) або JS-дія

Для типів page та category URL генерується автоматично при зміні slug — це виключає биті посилання.

Чому ми обрали @dnd-kit для drag-and-drop?

Бібліотека @dnd-kit/sortable — сучасний стандарт для перетягування на React. Вона працює в 2-3 рази швидше аналогів за рахунок використання closestCenter та вертикальної стратегії сортування. Ось як виглядає редактор:

import { DndContext, closestCenter } from '@dnd-kit/core';
import { SortableContext, arrayMove, verticalListSortingStrategy } from '@dnd-kit/sortable';

function MenuEditor({ items, onReorder }) {
  const [treeItems, setTreeItems] = useState(buildTree(items));

  const handleDragEnd = ({ active, over }) => {
    if (!over || active.id === over.id) return;

    const oldIndex = treeItems.findIndex(i => i.id === active.id);
    const newIndex = treeItems.findIndex(i => i.id === over.id);
    const reordered = arrayMove(treeItems, oldIndex, newIndex);

    setTreeItems(reordered);
    onReorder(reordered.map(({ id }, order) => ({ id, order })));
  };

  return (
    <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <SortableContext items={treeItems} strategy={verticalListSortingStrategy}>
        {treeItems.map(item => (
          <SortableMenuItem key={item.id} item={item} />
        ))}
      </SortableContext>
    </DndContext>
  );
}

Як уникнути N+1 при побудові дерева?

При завантаженні меню з вкладеністю розробники часто допускають N+1 запит — кожен рівень вибирається окремо. Ми використовуємо eager loading: одним запитом отримуємо всі пункти потрібного меню, а побудова дерева відбувається в пам'яті. Для 500 пунктів різниця — 3 мс проти 250 мс.

$items = MenuItem::where('menu_id', $menu->id)
    ->orderBy('order')
    ->get()
    ->toArray();

$tree = $this->buildTree($items);

Що дає кешування з інвалідацією?

Кешуємо результат збірки дерева на 1 годину в Redis. При будь-якій зміні (додаванні, видаленні, перестановці) кеш скидається через Observer. Приклад сервісу на Laravel:

class MenuService {
    public function getMenu(string $slug, string $locale): array
    {
        return Cache::remember("menu:{$slug}:{$locale}", 3600, function () use ($slug, $locale) {
            $menu = Menu::where('slug', $slug)->where('locale', $locale)->first();
            if (!$menu) return [];
            return $this->buildTree(
                $menu->items()
                    ->where('is_visible', true)
                    ->orderBy('order')
                    ->get()
                    ->toArray()
            );
        });
    }

    private function buildTree(array $items, ?int $parentId = null): array
    {
        return collect($items)
            ->where('parent_id', $parentId)
            ->map(fn($item) => array_merge($item, [
                'children' => $this->buildTree($items, $item['id'])
            ]))
            ->values()
            ->toArray();
    }
}

Інвалідація проста:

Menu::observe(MenuObserver::class);

class MenuObserver {
    public function saved(Menu $menu): void {
        Cache::forget("menu:{$menu->slug}:{$menu->locale}");
    }
}
Метрика Без кешу З кешем (Redis)
Час завантаження (100 пунктів) 150 мс 2 мс
Навантаження на БД (10 000 запитів/год) 10 000 1 (при інвалідації)

Мультиязичність реалізована через окремі записи menus з полем locale. Кеш розділяється за мовою, тому перемикання мови не впливає на продуктивність. При зміні slug сторінки URL у меню оновлюється автоматично — це забезпечує цілісність навігації.

Що входить у роботу?
  • Аналіз поточної структури навігації та вимог
  • Проектування моделі даних з урахуванням мультиязичності та вкладеності
  • Розробка drag-and-drop редактора на React (з можливістю вибору іншого фронтенду)
  • Серверна частина на Laravel або Node.js з кешуванням та інвалідацією
  • Інтеграція з CMS (WordPress, Drupal, Strapi та ін.)
  • Документація API та інструкція для контент-менеджерів
  • Навчання команди та гарантійна підтримка 30 днів

Процес роботи

  1. Аналітика — вивчаємо типи меню, кількість пунктів, частоту оновлень
  2. Проектування — описуємо модель, узгоджуємо інтерфейс
  3. Розробка — пишемо код паралельно з тестами
  4. Тестування — перевіряємо на N+1, кеш, продуктивність
  5. Деплой — розгортаємо в прод, налаштовуємо CI/CD

Строк розробки: від 2 до 5 днів залежно від складності. Вартість розраховується індивідуально — пишіть, оцінимо проект за один робочий день.

Отримайте консультацію: зв'яжіться з нами, і ми покажемо, як ваша команда зможе керувати меню без програмістів. Замовте розробку системи керування меню.

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

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

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060