This page builds on the Architecture and Data Model overview with frontend-specific detail. Read those first if you haven't.
Tokens are the contract between the frontend and apps. The frontend uses canonical tokens to request data or run mutations; apps register handlers for those tokens. This keeps the frontend backend-agnostic.
A query token describes a data request:
import { z } from 'zod/v4';
import { defineQueryToken } from '@laioutr-core/core-types/orchestr';
export const ProductBySlugQuery = defineQueryToken('ecommerce/product/by-slug', {
entity: 'Product',
type: 'single',
label: 'Product by slug',
input: z.object({
slug: z.string(),
}),
});
An entity component token describes a piece of entity data with a typed schema:
import { z } from 'zod/v4';
import { defineEntityComponentToken } from '@laioutr-core/core-types/orchestr';
export const ProductBase = defineEntityComponentToken('base', {
entityType: 'Product',
schema: z.object({
name: z.string(),
slug: z.string(),
}),
});
The same pattern applies to link tokens (relationships between entities), action tokens (mutations), and page type tokens. See Orchestr for how handlers are registered.
A page type token binds a type of page to its URL shape, required data, and Studio metadata:
import { z } from 'zod/v4';
import { defineQueryToken } from '@laioutr-core/core-types/orchestr';
import { definePageTypeToken } from '@laioutr-core/core-types/frontend';
const CategoryBySlugQuery = defineQueryToken('ecommerce/category/by-slug', {
entity: 'Category', type: 'single', label: 'Category by slug',
input: z.object({ slug: z.string() }),
});
// ---cut---
export const ProductListingPage = definePageTypeToken('ecommerce/product-listing-page', {
kind: 'dynamic',
studio: { label: 'Product Listing', group: 'Shop', icon: 'tags' },
requiredQueries: [
{
alias: 'category',
entityType: 'Category',
default: {
label: 'Listing Category',
token: CategoryBySlugQuery,
inputRules: { slug: { join: ['/', { var: 'route.params.slug' }] } },
},
},
],
pathConstraints: {
requiredParams: ['slug'],
default: '/categories/:slug+',
},
resolveFor: [{ referenceType: 'Category' }],
});
Routing is driven by the runtime config (RC): each page in the RC becomes a Nuxt route. The link resolver on the frontend turns references (e.g. "link to this product") into URLs by finding the page type that resolveFor that reference type. See Page Types for the full API.
The frontend provides extension points for cross-cutting concerns. Each feature defines a store and an adapter interface; apps plug in implementations:
useConsentStore() + consent adapters (e.g. Cookiebot)useTrackingStore() + tracking adapters (e.g. GTM)These adapters are registered by apps at module install time. The frontend core does not ship with any default adapter implementations.
Frontend
The Laioutr frontend is the customer-facing Nuxt app with pages, sections, and blocks composed in Studio, powered by a unified data layer (Orchestr) and a set of features you can extend. Start here to understand the product and navigate the docs.
Tech Stack
What you need to run the Laioutr frontend and what it is built from including Node, Nuxt, Vue, core packages, and optional apps.