Introduction

Key Concepts

The main ideas behind the Laioutr frontend including Nuxt app, Studio-driven content, Orchestr data layer, apps and features, and how they fit together.

Key concepts

This page gives a general overview of the key concepts behind the Laioutr frontend product. Understanding these will help you work with the frontend, extend it with apps, or integrate a new backend or feature.

The frontend is a Nuxt app

The Laioutr frontend is a Nuxt 3 application. It is the storefront or website your end customers see: product pages, category listings, search, cart, content pages, and so on. Everything that runs in the browser—routing, rendering, client-side state—lives in this single Nuxt app.

On top of Nuxt, the frontend uses Laioutr core packages (e.g. @laioutr-core/frontend-core) for shared behaviour: consent store, tracking store, link resolver, page and section rendering, and APIs for media library and Orchestr. Apps (Nuxt modules) then add UI components, sections, blocks, and backend integrations (Shopify, Shopware, Commercetools, etc.). So: Nuxt + Frontend Core + Orchestr + Apps form the frontend product.

Content comes from Studio

The structure and content of the frontend are not hard-coded. They are defined in Cockpit (Studio), where editors configure:

  • Pages – Which pages exist, their URL paths, and their page type (e.g. Home, Product Detail, Category Listing, Landing Page). Each page type describes the kind of page, its URL shape, and what data it needs.
  • Sections and blocks – The building blocks of each page. Sections are larger layout units (header, hero, product grid, footer); blocks are smaller content or feature units. Both are composed and configured in Studio (props, media, links, visibility).
  • Runtime config (RC) – The output of Studio is a project configuration (e.g. laioutrrc.json and related artifacts). That configuration describes pages, page variants, sections, blocks, and their props. When the frontend loads a route, it uses this config to know which page to render and which sections and blocks to show, with what data.

So the frontend is driven by configuration. The same Nuxt app can serve many different “sites” by changing the project config; editors change the experience without deploying new code.

Data comes from Orchestr

The frontend does not talk to Shopify, Shopware, or your CMS directly. It talks to a single Orchestr API (the backend-for-frontend) that runs as part of the same Nuxt app (server-side). Orchestr is the data layer:

  • Queries – Return entity IDs and metadata (e.g. product search, category listing, menu by alias). The frontend requests “products for this category” or “menu for this alias” and gets back a list of IDs and optional totals/facets.
  • Links – Resolve relationships (e.g. variants of a product, items in a menu). The frontend requests “variants for these product IDs” and gets back link results.
  • Component resolvers – Turn entity IDs into the actual entity data the UI needs (e.g. product name, price, image, SEO). So the frontend asks for “product base + prices + media for these IDs” and gets canonical components (pieces of data) per entity.
  • Actions – Mutations (e.g. add to cart, subscribe to newsletter). The frontend calls an action by token and input; Orchestr routes it to the right app handler.

All of this is token-based: the frontend uses canonical tokens (e.g. ProductBySlugQuery, ProductVariantsLink) and does not know which app implements them. Apps register handlers for those tokens and call their backends; Orchestr caches and composes the result. So the frontend stays backend-agnostic; swapping or adding a backend is done by adding or changing apps, not by changing the storefront code.

Pages, page types, and routing

A page in the config has an id, a type (a page type token name, e.g. ecommerce/product-detail-page), and a path (e.g. /products/:slug). Page types are defined in code and describe:

  • Whether the page type is static (many instances, e.g. landing pages) or dynamic (typically one per project, e.g. Home, Product Detail).
  • Path constraints – How the URL looks (exact path, default pattern, required params).
  • Required queries – What data the page needs and how it is bound to the route (e.g. product by slug, search by query param).
  • Studio metadata – Label, group, icon for the “Add page” and page switcher UI in Cockpit.
  • resolveFor – Which reference types (e.g. Product, Category) this page type resolves, so link resolution can turn “link to this product” into the correct URL.

So routing is driven by the RC: each page in the config becomes a route. The link resolver on the frontend can resolve links by page (by id), by page type (with params), or by reference (e.g. Product slug → Product Detail page URL). Page types are the bridge between “what kind of page this is” and “what URL and data it has”.

Canonical types and tokens

Laioutr uses canonical types so that the frontend and all apps speak the same language. Products, categories, media, cart, filters, sortings—these are defined once (e.g. in @laioutr-core/canonical-types and @laioutr-core/core-types) and used everywhere. So a section that displays a “product tile” expects a canonical Product shape (or a subset of components); it does not care whether the data came from Shopify or Shopware.

Tokens are the same idea for behaviour: query tokens, link tokens, action tokens, page type tokens. They are unique identifiers (often with type metadata) that the frontend uses to request data or run an action. Apps implement handlers for those tokens. So the frontend says “run ProductsByCategorySlugQuery with this input”; Orchestr finds the handler (e.g. from the Shopify app) and returns the result. Tokens are the contract between the frontend, Orchestr, and apps.

Features and adapters

The frontend ships with features that are themselves abstracted so you can plug in different implementations:

  • Consent management – One consent store; you plug in a consent adapter (e.g. Cookiebot app) or build your own. Other features (e.g. tracking) read from the same store.
  • Tracking – One tracking store and event shape; you plug in tracking adapters (e.g. GTM app) or your own. Adapters can be gated by consent.
  • Media library – Editors pick assets in Cockpit from a list of media library providers. Each provider (e.g. Shopify, Shopware, your DAM) is a media adapter that implements list (and optionally upload).
  • PWA, page types, multi-language, currencies, authentication – Similarly, the platform provides the concept and extension points; apps or config fill in the behaviour.

So the frontend product is layered: a stable core (Nuxt + Frontend Core + Orchestr), canonical types and tokens, and then features and apps that implement or extend those concepts. As a developer, you can add a new app (with Orchestr handlers and sections), implement a new adapter (consent, tracking, media), or add a new page type—without changing the core.

Together, these concepts let you build a storefront that is configurable in Studio, powered by any backend via Orchestr and apps, and extensible with new features and adapters. For more, see Features and Orchestr.