Документація

Поточна структура: v1.0

getstarted

Підключення Nuxt module:

orders

Guest order flow працює без логіну: storefront тримає кошик локально, backend створює order зі snapshot items, а virtual payment переводить payment у PAID.

Повний guest flow

  1. На product detail додай у кошик productId, optional configurationId, configurationLabel, price і quantity.
  2. На checkout сформуй бізнес-payload через useCheckoutForm(). Backend створює opaque guestToken, а useCheckout() автоматично передає Idempotency-Key.
  3. Business order завжди стартує як NEW; virtual provider одразу створює payment PAID, а COD і prepayment залишають payment PENDING.
  4. Після checkout веди покупця на /orders/:id/:token і став Referrer-Policy: no-referrer.

Product-detail add-to-cart приклад:

Order status page приклад:

Inventory mode

  • Shop inventory mode налаштовується в marketing /shops: TRACKED або UNTRACKED.
  • Джерело залишку одне: configuration stock override, або product stock fallback, або unmanaged null.
  • Stock атомарно перевіряється і списується тільки коли payment стає PAID.
  • UNTRACKED робить storefront availability оптимістичною і не списує stock під час payment.

components

Портативні storefront UI wrappers над composables: готовий fallback markup для швидкого старту і scoped slots для повної кастомізації темою.

Component API поки експериментальний: breaking changes допускаються до першого stable release.

StorefrontProductCard

Приймає raw storefront product, нормалізує card view model і basket actions та дає fallback markup, named slots або повний default slot.

Для display-конвертації передай `currency` і готовий Decimal-рядок `currencyMultiplier` з `useConfig()`. `viewModel.product.price.formatted` зміниться, а `price.value` і basket action залишаться точними decimal-рядками в базовій валюті.

StorefrontProductGrid

Pure structural grid для готового локального масиву товарів, наприклад recently viewed; не створює fetch lifecycle.

StorefrontManagedProductGrid

Connected grid над keyed singleton useProducts store. state-key ідентифікує каталог, а slots перевизначають product, skeleton, empty та error states.

StorefrontCatalogFilters

UI wrapper для filter draft: нормалізує text/color/numeric selection, numeric range inputs та віддає apply/reset runtime actions через slot.

StorefrontCatalogPagination

Pure pagination wrapper: обчислює totalPages, межі, ellipsis і page items для переданих page/total/perPage без fetch lifecycle.

StorefrontManagedCatalogPagination

Connected pagination для keyed singleton useProducts store: читає meta та викликає setPage() того самого каталогу без нового fetch watcher.

composables

useConfig

Глобальний composable конфігурації storefront. Зберігає locale через useState для синхронності SSR/CSR.

  • `brand` - назва бренду поточного магазину з storefront config
  • `theme` - кольори `light`, `dark`, `accents` і `background` з окремими тайлами, alpha-градієнтами, позиціями та кутами для світлої й темної тем.
  • `customHtml` - trusted HTML-блоки head, bodyStart і bodyEnd поточного магазину
  • `locale` - Ref<string> з поточним значенням локалі
  • `setLocale(locale)` - оновлює locale і тригерить watch-refetch у composables
  • `baseCurrencyCode` містить валюту каталожних цін, а `currencies` — лише дозволені для показу покупцю валюти з ручним `baseAmountPerUnit` за 1 одиницю.
  • `currency` — cookie-backed Ref поточної валюти відображення; `setCurrency(code)` приймає лише код із `currencies` і безпечно повертається до базової валюти, якщо код більше недоступний.
  • `currencyRate` — decimal-рядок з кількістю одиниць базової валюти за 1 одиницю вибраної; `currencyMultiplier` теж decimal-рядок і вже обчислений бібліотекою без JS-ділення.
  • `convertPrice()` і `multiplyPrice()` повертають decimal-рядки без проміжного округлення. Лише `formatPrice()` перетворює результат для візуального форматування через Intl; базова ціна не змінюється.
  • Валюта покупця поки лише display context: передай `displayCurrencyCode` у `createPayload()`. Order і payment лишаються в базовій валюті, а відповідь order містить immutable `currencySnapshot` із часом, курсами та base/display prices.

useCategories

Async composable над shared storefront client. Shop не передається з фронта: контекст уже резолвиться на бекенді через publicToken.

  • `tree` - готове nested дерево категорій з API
  • `pending` - стан завантаження
  • `error` - стан помилки
  • `refresh` - ручний refetch

TS interface і приклад формату документа, який повертається у tree:

useProductFilters

Loads available filters for current keyed useProducts() query state.

  • Для координації з products передай той самий explicit key; state-only filter composables читають його query state.
  • За потреби можна перевизначити categorySlug/categoryId через params.

useCatalogScopeFilters

Shortcut composable for catalog scope filters (current category + descendants) with optional parent inheritance.

  • Always requests scope=catalog and is intended for catalog-facing filters UI.
  • inheritParent defaults to true and can be overridden when needed.
  • disableMode keeps filters visible, adds filterItem.disabled/value.disabled, and marks value disabled when not selected with count=0.
  • onlyAvailable приховує zero-count values і порожні фільтри, але зберігає активні значення для скидання. TRACKED враховує наявність, UNTRACKED ігнорує stock.

URL і draft стан каталогу

useCatalogFiltersRoute зберігає застосовані фільтри у читабельному URL, а useProductFiltersDraft відокремлює незастосовані зміни sidebar.

  • URL використовує повторювані filter[filter-slug] параметри; невідомі slug і значення ігноруються.
  • Зміни draft не перезавантажують товари; apply() комітить всю мапу один раз.
  • Numeric підтримує presets і один custom min/max token __range__:<from>:<to>; reference UI робить ці режими взаємовиключними.
  • Facet counts виключають власний активний фільтр. Color values містять color для swatch UI.

useProductFilter

Composable для одного фільтра: готує values із selected/disabled станами і перемикає значення через useProductsQuery().

  • `values` - значення фільтра з selected/disabled станами для UI.
  • `toggle(valueSlug)` перемикає значення; `clear()` очищає цей фільтр.

useProducts

З explicit key повертає singleton catalog store у межах поточного Nuxt app/request; без key створює ізольований instance.

  • Однаковий explicit key повертає той самий store object і один fetch/watch lifecycle. Для окремого каталогу використовуй інший стабільний key.
  • Повертає items, total, page і perPage для pagination UI.
  • Supports sort: updated-desc | updated-asc | created-desc | created-asc | price-desc | price-asc.
  • Якщо catalog filters збігаються з quick filters товару, item.catalogSelection містить одну доступну/найдешевшу конфігурацію та відповідну картинку, ціну і stock.

Typical flow: managed grid володіє keyed products lifecycle, а filters і pagination працюють з тим самим store/query key.

useProduct

Loads one published product by storefront slug through the public storefront token.

  • `slug` is required and maps to GET /api/storefront/products/:productSlug.
  • `product.characteristics` contains ready UI characteristics derived from product filter values.
  • Product descriptions stay in `product.translations[*].descriptionHtml` and follow the active locale.

usePage

Завантажує одну публічну контентну сторінку поточного магазину за slug або ID.

  • Передай рівно один lookup: `slug` або `id`.
  • `page` містить локалізовані title, contentHtml, pictures та metadata.
  • Сторінки створюються в admin.a.zynk.uno/pages/shop і одразу доступні storefront.

useProductQuickSelection

Керує швидким вибором значень у товарі та обчислює активну конфігурацію, ціну, стару ціну, кількість і доступні картинки.

  • За замовчуванням вибирає найдешевшу доступну конфігурацію; стратегія `FIRST` вибирає першу доступну.
  • Порожні overrides успадковують значення товару, а `stockQty = null` означає, що кількість не менеджиться і конфігурація доступна.
  • `selectedConfiguration` містить стабільний UUID вибраної конфігурації, а `prices` надає ефективні значення для всіх комбінацій.
  • У межах правила картинки умови працюють як AND, між правилами як OR; неповні правила не обмежують невказані фільтри.
  • initialConfigurationId відновлює конфігурацію з картки/URL; невалідний UUID безпечно повертає стандартний CHEAPEST/FIRST вибір.

useBasket

Client-side basket composable with useState source of truth, localStorage persistence, and product/configuration line identity.

  • Hydrates basket from localStorage on client mount only (no server reads).
  • Supports isolated baskets via storageKey, for example basket:default or basket:shop-123.
  • lineId is productId:configurationId; use it for quantity changes and removal.

useCheckoutForm

Володіє базовою customer-формою, provider payment values, opt-in localStorage та формуванням чистого checkout payload.

  • `form` містить name, phone, email, country, city, address, postalCode, comment і doNotContact.
  • До створення order `paymentMethods`, `selectedPaymentProviderId`, `selectedPaymentMethod` і `visibleFields` містять повний UI-контракт: title, description, instructions, labels, hints, options та constraints. `getOrder()` потрібен уже для історичного snapshot.
  • `dataName` зв’язує provider field з allowlisted `customer.*` або власним `payment.<fieldKey>`; schema inputs читаються і змінюються через `getValue()` / `setValue()`.
  • `persistCustomer()` викликається після успішного order; comment і payment values у localStorage не потрапляють.
  • `createPayload()` матеріалізує customer, items, selected provider і validated paymentValues без transport keys.

useCheckout

Action composable for storefront guest orders: list payment methods, create an order, and load its status by opaque token.

  • `createOrder(payload, options?)` додає Idempotency-Key, створює order + payment і повертає backend-generated `{ order, guestToken }`; після network failure незмінний payload автоматично повторно використовує pending key.
  • `getOrder(orderId, guestToken)` loads the public order status page data.

useCatalogSearch

Локальний рейтинговий пошук товарів з debounce від 3 символів за назвою, SKU та штрихкодами, готовим imageUrl і прямим переходом на товар.

  • `term` зберігається локально і не пишеться в query.search.
  • Результати ранжуються backend за exact SKU (100), barcode (95), name (90), потім prefix і contains; мінімальна довжина запиту — 3 символи.
  • `select(item)` очищає пошук і відкриває `/products/:slug`; `imageUrl` надає перевагу thumbnail і використовує primary як fallback.