Apps

App Development

Overview of the Laioutr app development docs and how to use them.

Overview

A Laioutr app is a standard Nuxt module, packaged as an npm package. If you have built a Nuxt module before, you already know 80% of what you need. The Laioutr-specific parts are a registration call (registerLaioutrApp), a config key convention, and a set of APIs for connecting data sources and UI components to the platform.

The Custom App Development section explains how to build, configure, and maintain Laioutr apps. These are Nuxt modules that integrate external systems (commerce, CMS, analytics, hosting, etc.) with the Laioutr platform.

If you want to:

  • Add new data sources to your Laioutr frontend via Orchestr.
  • Ship sections and blocks that editors can use in Studio.
  • Package your integration as a reusable Nuxt module that can be installed via npm.

...this is the place to start.

What an app can do

Laioutr apps are the primary extension mechanism for the platform. Here is what you can build with one:

  1. Provide sections and blocks for Studio. Editors drag and drop your components onto pages, configure them through the Studio sidebar, and preview them in real time.
  2. Connect external data sources via Orchestr. Write query handlers, component resolvers, and link resolvers to pull data from commerce platforms, CMS systems, or any API into the frontend's unified data layer.
  3. Integrate third-party services. Analytics, newsletter signup, search providers, payment gateways, or anything that needs to hook into the frontend lifecycle or inject scripts.
  4. Define custom page types. Register new page types (e.g. a store locator or a lookbook) that editors can create and manage in Studio.
  5. Add media library connections. Connect external asset sources (DAM systems, CDNs) so editors can browse and select media from Studio.

Component authoring overview

Laioutr uses a definition-first approach for sections and blocks. You start by declaring what your component is and what it needs, and the platform takes care of the rest.

The definition is the contract

Every section and block exports a definition object created with defineSection() or defineBlock(). This definition declares the component's name, label, and schema (the fields that appear in the Studio sidebar when an editor selects your component).

import { defineSection, definitionToProps } from '#imports';

export const definition = defineSection({
  component: 'SectionHeroBanner',
  studio: {
    label: 'Hero Banner',
  },
  slots: [
    { name: 'default', studio: { label: 'Content' } },
  ],
  schema: [
    {
      label: 'Content',
      fields: [
        { type: 'text', name: 'heading', label: 'Heading' },
        { type: 'media', name: 'backgroundImage', label: 'Background Image' },
        { type: 'text', name: 'ctaLabel', label: 'Button Label' },
        { type: 'link', name: 'ctaLink', label: 'Button Link' },
      ],
    },
  ],
});

Props from the definition

Instead of writing Vue props by hand, you use definitionToProps() to infer props directly from the definition. This eliminates duplication and guarantees that your component's props always match what Studio sends.

Both the definition and the component logic live in the same .vue file. The definition is exported from a regular <script lang="ts"> block, and definitionToProps() is used in <script setup>:

<script setup lang="ts">
const props = defineProps(definitionToProps(definition));
</script>

The definition is the single source of truth. Studio reads it to build the sidebar editor, Frontend Core reads it to wire up data, and your component reads it to define its props. See Section Definitions and Block Definitions for the full guide.

Section, block, and slot hierarchy

Understanding how pages are composed helps you decide whether to build a section or a block.

Page → Variant → Header / Body / Footer → Sections → Slots → Blocks
ConceptRoleExample
SectionA top-level page component that fills a row of the page layout.Hero banner, product grid, testimonial carousel, newsletter signup
BlockA smaller component that lives inside a section's slot.A single slide in a carousel, a product card in a grid, a FAQ item
SlotA named insertion point inside a section where blocks are placed.A carousel section might have a slides slot that accepts slide blocks

Sections are what editors add directly to a page region (header, body, footer) in Studio. Blocks are what editors place inside sections, into the slots that the section defines. This two-level composition keeps sections flexible without making them monolithic.

What you will find here

  • App Starter How to create a new Laioutr app from the official starter template, understand the project structure, and run the local playgrounds.
  • App Configuration How laioutrrc.json, runtime config, and per-app options work, and how configuration is passed into your Nuxt module.
  • Section Definitions How to create section definitions with Studio metadata, slots, and schemas.
  • Block Definitions How to create block definitions, including standalone vs non-standalone blocks.
  • Schema Fields Reference for all field types available in section and block schemas, including defaults, fallbacks, and field decorators.
  • Platform Dependencies Nuxt modules and versions already installed by the Laioutr platform. Check before adding dependencies to your app.
  • Coding Standards & Best Practices Conventions for Orchestr handlers, sections/blocks, error handling, logging, and testing, plus practical guidance on designing reliable integrations.

Together, these guides help you move from a blank repository to a production-ready Laioutr app that fits cleanly into the overall frontend and CI/CD flows.

  • Local Setup. Set up your development environment and connect Studio to localhost.
  • Architecture. How the frontend, Orchestr, and Studio fit together.
  • Extensibility. The extension points available to apps.
  • Orchestr. The data composition layer your app's handlers plug into.