Sylius
Overview
The @laioutr-app/sylius package integrates a Laioutr-powered Nuxt app with Sylius, the open-source headless eCommerce platform built on Symfony. It talks to the Sylius Shop API v2 (/api/v2/shop) via openapi-fetch using a TypeScript client generated from the Sylius OpenAPI spec.
The package registers with the Laioutr orchestr (queries, actions, links, component resolvers) and maps Sylius resources to canonical ecommerce entities (Product, ProductVariant, Category, MenuItem, BreadcrumbItem, Cart, CartItem).
MVP scope
This release is intentionally narrow. Anything not listed is out of scope.
- Read – Product, ProductVariant (PLP, PDP, variant selection), Category, MenuItem, BreadcrumbItem (taxon-derived navigation).
- Write – Cart line-items only: Add, Update quantity, Remove. No checkout.
- Out of scope – Customer authentication, addresses, payments, shipping, CMS pages, wishlist, bundles, reviews, attributes, associations, promotions.
Configuration requirements
The module expects configuration under the key @laioutr-app/sylius in nuxt.config.ts (or via runtimeConfig).
Module options
| Option | Type | Description |
|---|---|---|
apiURL | string | Required. Sylius Shop API v2 base URL, e.g. http://localhost/api/v2/shop or https://your-store.example.com/api/v2/shop. The origin is used to build the API client; the path identifies the Shop API. |
defaultLocale | string | Fallback Accept-Language sent with every request when the orchestr client environment does not provide a locale. Default: en_US. |
imageFilter | string | LiipImagine filter Sylius applies server-side before returning image URLs. Sent as the imageFilter query parameter on every product/variant fetch, so image.path comes back as a ready-to-use absolute URL. Default: sylius_large. |
itemsPerPage | number | Default pagination size for list queries (e.g. category PLPs). Default: 20. |
Example configuration
export default defineNuxtConfig({
modules: ['@laioutr-app/sylius'],
'@laioutr-app/sylius': {
apiURL: process.env.SYLIUS_SHOP_API_URL ?? 'http://localhost/api/v2/shop',
defaultLocale: 'en_US',
imageFilter: 'sylius_large',
itemsPerPage: 20,
},
});
Runtime behavior
- Shop API client – A
createSyliusClientinstance is built per request withapiURL, the activelocale(from the orchestrclientEnvordefaultLocale),itemsPerPage, andimageFilter. Headers default toAccept: application/ld+jsonandAccept-Language: <locale>. The client is exposed to handlers viacontext.syliusClient. - Hydra responses – Sylius returns JSON-LD with Hydra collections (
hydra:member,hydra:totalItems). The client unwraps collections into{ items, total }before they reach the orchestr handlers. - No Admin API – The MVP does not call the Sylius Admin API. Everything goes through the Shop API.
- Write surface is single-sourced – By design, only the client module issues non-GET HTTP requests (
createCart,addCartItem,changeCartItemQuantity,removeCartItem). Orchestr handlers, mappers, and helpers are read-only and delegate every write to the client.
Capabilities
The package implements Laioutr’s canonical ecommerce types via the orchestr. For exact types and payloads, refer to @laioutr-core/canonical-types and the package source.
Queries
- Cart
- GetCurrentCartQuery – Returns the current cart id (the cart token from cookie) if a cart exists; otherwise
{ id: undefined }. No cart is created on read.
- GetCurrentCartQuery – Returns the current cart id (the cart token from cookie) if a cart exists; otherwise
- Category
- CategoryBySlugQuery – Resolves a Sylius taxon by slug; returns the canonical entity id (
taxon:<code>).
- CategoryBySlugQuery – Resolves a Sylius taxon by slug; returns the canonical entity id (
- Menu
- MenuByAliasQuery – Returns a flat, parent-before-children list of taxon entity ids. The
aliasargument is resolved directly as a Sylius taxon code (e.g.MENU_CATEGORY); there is no separate alias-to-code mapping. The tree is BFS-walked up to a depth of 5.MenuItem.parentIdis never emitted because the Shoptaxon.showschema does not exposeparent— reconstruct the tree top-down fromchildIds.
- MenuByAliasQuery – Returns a flat, parent-before-children list of taxon entity ids. The
- Product
- ProductBySlugQuery – Resolves a product by slug; returns the Sylius product
codeas id. - ProductsByCategorySlugQuery – Listing by taxon slug with pagination and sort. Sortings:
name:asc,name:desc,price:asc,price:desc(defaultname:asc). Filters: none in MVP. The Syliustaxonquery parameter is recursive — filtering by a parent IRI returns products in that taxon and all descendants.
- ProductBySlugQuery – Resolves a product by slug; returns the Sylius product
Actions (cart line-items)
- CartAddItemsAction – Adds line items to the cart. Creates the cart on demand if no
sylius-cart-tokencookie is set (or if the existing token no longer resolves), thenPOST /api/v2/shop/orders/{tokenValue}/itemsper item. Only items withtype === 'product'are processed. - CartUpdateItemsAction –
PATCHeach item’s quantity. The canonicalitemIdis decoded as<cartToken>::<orderItemId>; items without a quantity are skipped. - CartRemoveItemsAction –
DELETEeach item by decodedorderItemId. Throws if no cart token is present.
There is no checkout action in this package.
Links
- ProductBreadcrumbLink – Breadcrumb trail derived from the product’s
mainTaxon. Uses Sylius’s/api/v2/shop/taxon-tree/{code}/pathendpoint to fetch the full ancestor chain (root → leaf) in a single request. - ProductVariantsLink – Lists variant codes per product via
/api/v2/shop/product-variants?product[]=.... - CartItemsLink – Resolves a cart token to its line items, exposing each as
<cartToken>::<orderItemId>. - CartItemProductVariantLink – Resolves a cart item to its underlying variant code.
Component resolvers
- Product – Maps to
ProductBase,ProductInfo,ProductMedia,ProductPrices,ProductSeo,ProductDescription,ProductFlags,ProductDefaultVariant. Prices usedefaultVariantData.price/originalPrice;isOnSaleandstrikethroughPriceare derived from the delta.isStartingFromis true when the product has more than one variant. Cache: 1 day, withpricessub-component at 15 minutes. - ProductVariant – Maps to
ProductVariantBase,ProductVariantInfo,ProductVariantPrices,ProductVariantOptions,ProductVariantAvailability. Options are resolved through a per-request cache that fetches/product-optionsand/product-option-valuesonce and reuses the result for concurrent resolves. Cache: 1 day,pricesat 10 minutes,availabilityuncached. - Category – Maps a taxon to
CategoryBase(slug, title). Cache: 1 day. - MenuItem – Maps a taxon to
MenuItemBase(type: 'link', name, link reference,childIds).parentIdis not emitted. Cache: 1 day. - BreadcrumbItem – Maps a taxon to
BreadcrumbItemBase(name, link reference). Cache: 1 day. - Cart – Maps a cart token to
CartBase(totalQuantity) andCartCost(subtotal, total, tax) in the cart’scurrencyCode. - CartItem – Maps
<cartToken>::<orderItemId>toCartItemBase(type'product', quantity, title, subtitle) andCartItemCost(single, subtotal, total).
Entity ID conventions
The connector uses stable, decode-friendly ids so other handlers can round-trip them without extra lookups:
| Entity | ID format | Example |
|---|---|---|
| Product / ProductVariant | Sylius code | MUG-001 |
| Category / MenuItem / BreadcrumbItem | taxon:<code> | taxon:MENU_CATEGORY |
| Cart | Sylius cart tokenValue | 7a9c… |
| CartItem | <cartToken>::<orderItemId> | 7a9c…::42 |
Image provider
- Provider name:
sylius - How it works: Product and variant media are mapped to the canonical
MediaImagetype withsources[].srcset to the Syliusimage.path. Because the client sendsimageFilteron every request, that path is already a fully-resolved URL likehttp://your-store/media/cache/resolve/sylius_large/<hash>.webp— no client-side transformation is needed.
Backend requirements
- Sylius version – A Sylius release that exposes the API Platform–based Shop API v2 (Sylius 1.13+ recommended).
- Channel – A storefront channel with at least one locale, currency, and hostname matching the storefront.
- Catalog – Products with taxons, variants, prices, and images assigned to the active channel. Slugs translated for the locales you serve so slug-based queries resolve.
- Menu root taxon – A taxon (e.g.
MENU_CATEGORY) that acts as the storefront menu root. Its code is what the frontend passes asaliastoMenuByAliasQuery. - Image filter – A LiipImagine filter set (default
sylius_large) defined in the Sylius config. - CORS / network – The Nuxt server must reach the Shop API; the browser does not call the Shop API directly.
Cookies and session
| Cookie | Purpose |
|---|---|
sylius-cart-token | Sylius tokenValue for the current cart/order. Set on cart creation and read on every cart query/action. Options: httpOnly, secure, sameSite=lax, path=/, maxAge=30d. |
There is no customer/session cookie in the MVP — there is no customer auth.
Codegen
Sylius types are generated from the OpenAPI spec into src/runtime/server/client/sylius-types.ts and committed:
pnpm gen:sylius
The script fetches /api/v2/docs from the configured Sylius backend (default http://localhost) and runs openapi-typescript against it.
Summary checklist for developers
- Sylius instance – Shop API v2 reachable; channel(s) configured with locales, currencies, hostnames; LiipImagine
sylius_large(or your chosen filter) defined; menu root taxon (e.g.MENU_CATEGORY) created. - Catalog data – Products with taxons, variants, prices, images, and translated slugs.
- Nuxt config – Add
@laioutr-app/syliustomodulesand setapiURL(plus optionaldefaultLocale,imageFilter,itemsPerPage). - Environment – Put the API URL in env vars; ensure the Nuxt server can reach the Sylius origin.
- Frontend – Use the canonical queries, actions, links, and resolvers from your UI. Pass the menu root taxon code as the menu
alias. Reconstruct the menu tree top-down fromchildIds. - Images – Use the
syliusNuxt Image provider for Sylius media. - Checkout – Plan the checkout flow outside this package (it is not in MVP scope).
Changelog
Version history is maintained in CHANGELOG.md in the public repository laioutr/app-sylius.
Pimcore
Developer documentation for the Laioutr Pimcore app. Connect your Laioutr-powered Nuxt app to Pimcore and fetch data through its native REST API.
Commercetools
Developer documentation for the Laioutr Commercetools app package. Connect your Nuxt frontend to Commercetools via the Platform API with anonymous or client-credentials auth.