
# Pages Overview

Pages are server-rendered (SSR) using a declarative component tree. Each page declares a `name`, a `path`, optional SEO `meta`, and a `components` array of nested components. Pages render your tables' records, host forms that write to them, embed interactive islands, and expose public-facing content — all from configuration, no custom React required.

A page needs at minimum a `name` and a `path`. Everything else — metadata, access control, scripts, dynamic collection routes, markdown content, view transitions, and per-page toasts — is optional and layered on top.

```yaml
pages:
  - name: Home
    path: /
    meta:
      title: Welcome
      description: The fastest way to ship internal tools.
    components:
      - type: hero
        content: Build apps from config
      - type: container
        children:
          - { type: text, content: 'Get started in minutes.' }
```

## Page Properties

Each entry in the `pages` array accepts the following properties.

| Property         | Description                                                                                                                                                       |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`             | Optional unique identifier for the page. Auto-generated when omitted.                                                                                             |
| `name`           | Human-readable page name (used in navigation and admin listings).                                                                                                 |
| `path`           | URL route. Static (`/about`), root (`/`), or dynamic with a `:param` segment (`/blog/:slug`). See [Routing](#routing).                                            |
| `meta`           | SEO and document-head metadata: title, description, Open Graph, Twitter cards, favicons, structured data. See [SEO & Metadata](/en/docs/seo-meta).                |
| `components`     | Array of component definitions forming the page's render tree. See [the component model](#the-component-model).                                                   |
| `access`         | Access control: `'all'` (public), `'authenticated'`, a role array `['admin']`, or `{ require, redirectTo }`. Defaults to `'all'`.                                 |
| `collection`     | Template configuration that generates one route per table record (dynamic pages). See [Collection Pages](#collection-pages).                                      |
| `markdown`       | Render the entire page body from a markdown file or inline string, with layout and table-of-contents options. See [Markdown Pages](#markdown-pages).              |
| `source`         | File-based content source (`source.file`) for a `content` component — loads markdown from disk with frontmatter. Mutually exclusive with `content`.               |
| `layout`         | Named layout sections (e.g. a data-bound `sidebar`) wrapping the page body. See [Layouts & Sidebars](#layouts--sidebars).                                         |
| `scripts`        | Client-side scripts, feature flags, external dependencies, and config data injected into the page. See [Interactivity & Scripts](/en/docs/interactivity-scripts). |
| `vars`           | Page-scoped variables (`key`/`value` pairs) referenceable via `$vars.*` in component templates.                                                                   |
| `toasts`         | Page-level toast notification config (position, default duration).                                                                                                |
| `viewTransition` | Page navigation animation: `fade`, `slide` (with `direction`), or `none`, plus `duration`.                                                                        |
| `sitemap`        | Per-page sitemap entry (priority, change frequency) or `false` to exclude the page from the sitemap.                                                              |
| `rss`            | Enable an RSS feed for a collection page — `true` for defaults, or `{ limit }` to cap item count.                                                                 |

```yaml
pages:
  - name: About
    path: /about
    access: all
    meta: { title: 'About Us' }
    viewTransition: { type: fade, duration: 200 }
    components:
      - { type: text, tag: h1, content: 'About' }
```

## Routing

The `path` property declares the URL where a page is served.

| Path form     | Example       | Description                                                                 |
| ------------- | ------------- | --------------------------------------------------------------------------- |
| Root          | `/`           | The home page.                                                              |
| Static        | `/about`      | A fixed route.                                                              |
| Nested static | `/checkout`   | Any number of static segments.                                              |
| Dynamic       | `/blog/:slug` | A `:param` segment captures a value available to the page as a route param. |
| Record id     | `/tasks/$id`  | Dynamic detail routes resolve the matching record into `$record.*`.         |

Dynamic routes are most often paired with a `collection` block so one page definition generates a route per record. See [Collection Pages](#collection-pages).

## The Component Model

A page's `components` array is a tree. Every component has a `type` (one of ~80 built-in component types) and a set of properties. Components compose through a shared module system, so the same cross-cutting properties are available almost everywhere:

| Shared property | Available on              | Description                                                                                                           |
| --------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `props`         | Almost all components     | Key-value bag of styling/config attributes rendered as HTML attributes (e.g. `className`, `variant`).                 |
| `content`       | Content/layout components | Inline text or markdown; supports `$record.*`, `$vars.*`, and `$t:key` (translation) substitution.                    |
| `children`      | Container-like components | Nested child component definitions.                                                                                   |
| `dataSource`    | Data-bound components     | Binds the component to a table (filter, sort, pagination, single/search mode). See [Data Binding](#data-binding).     |
| `visibility`    | Most components           | Conditional display based on auth state — server-rendered, hidden client-side when conditions are unmet.              |
| `responsive`    | Most components           | Per-breakpoint overrides for responsive behavior.                                                                     |
| `interactions`  | Interactive components    | Click actions, hover effects, and entrance animations. See [Interactivity & Scripts](/en/docs/interactivity-scripts). |
| `action`        | Form/button components    | Behavior to run on interaction — `crud`, `auth`, `navigate`, `automation`, with `onSuccess`/`onError` handlers.       |
| `i18n`          | Content components        | Localized content variants per language.                                                                              |

:::callout
**Variable substitution.** Component `content` and `props` values resolve three reference families at render time: `$record.<field>` (current data-source record), `$vars.<key>` / `$currentUser.<path>` (page and session context), and `$t:key` (translation keys, with fallback). The page-level `markdown` source additionally exposes `$frontmatter.*`.
:::

Components are grouped into categories, each documented on its own page:

| Category                                                  | Examples                                                                                         |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| [Layout](/en/docs/layout-components)                      | hero, container, flex, grid, responsiveGrid, card, sidebar, modal, tab-panel                     |
| [Content](/en/docs/content-components)                    | text, code, toc, accordion, blockquote, alert, custom-html                                       |
| [Data](/en/docs/data-components)                          | data-table, list, gallery, kanban, calendar, chart, kpi, timeline                                |
| [Form Controls](/en/docs/form-controls)                   | input, textarea, select, checkbox, radio, switch, slider, date-picker, file-upload, number-input |
| [Overlays](/en/docs/overlay-components)                   | dialog, drawer, popover, tooltip, hover-card, alert-dialog, toast, progress, skeleton            |
| [Navigation](/en/docs/navigation-components)              | navigation-menu, dropdown-menu, breadcrumb, tabs, pagination, toggle, button-group, menubar      |
| [Media](/en/docs/media-components)                        | image, icon, video, audio, iframe, carousel, aspect-ratio                                        |
| [Display](/en/docs/display-components)                    | static-table, command, empty-state, resizable, scroll-area, speech-bubble, status-indicator      |
| [Feedback](/en/docs/feedback-components)                  | progress, spinner, skeleton                                                                      |
| [Interactive](/en/docs/interactive-components)            | button, link, alert, badge, button-group                                                         |
| [Specialty](/en/docs/specialty-components)                | wizard, reorderable-list, language-switcher, comments, ai-chat                                   |
| [Social](/en/docs/social-components)                      | comments, commentCount, ai-chat, sharing                                                         |
| [SEO & Metadata](/en/docs/seo-meta)                       | title, description, Open Graph, Twitter cards, JSON-LD, favicons                                 |
| [Interactivity & Scripts](/en/docs/interactivity-scripts) | scripts, interactions, auto-save, custom-html                                                    |

## Data Binding

Bind any data component (or container) to a table with `dataSource`. The bound records expose their fields to descendants through `$record.<field>` references.

| `dataSource` property | Description                                                                                                                       |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `table`               | Table name to bind to (validated against `app.tables`).                                                                           |
| `fields`              | Specific fields to fetch (omit to fetch all).                                                                                     |
| `filter`              | Array of `{ field, operator, value }` conditions combined with AND. Operators: `eq`, `neq`, `contains`, `gt`, `lt`, `gte`, `lte`. |
| `sort`                | Array of `{ field, direction }` rules applied in order (primary, secondary).                                                      |
| `pagination`          | `{ pageSize, style }` — `style: numbered` renders page navigation; `style: loadMore` renders a Load More button.                  |
| `mode`                | `single` resolves one record by a route `param`; `search` filters across `searchFields` with `debounce` and `maxResults`.         |
| `id`                  | Identifier for cross-component data-source references.                                                                            |

```yaml
- type: data-table
  dataSource:
    table: tasks
    filter:
      - { field: status, operator: neq, value: archived }
    sort:
      - { field: created_at, direction: desc }
    pagination: { pageSize: 25, style: numbered }
```

:::callout
**Current-user scoping.** `$currentUser.*` resolves per-request during SSR (never cached across users): `$currentUser.id`, `$currentUser.role`, `$currentUser.email`, `$currentUser.isUnrestricted` (global-admin bypass), and `$currentUser.assignments.<table>` (flattened record ids the user is assigned to). Pages using `$currentUser` return `401` when accessed unauthenticated.
:::

## Collection Pages

A `collection` block turns one page definition into a route per table record. The page's `path` must include a dynamic `:param` segment matching `slugField`.

| `collection` property | Description                                                                             |
| --------------------- | --------------------------------------------------------------------------------------- |
| `table`               | Table name to generate collection pages from (must exist in `app.tables`).              |
| `slugField`           | Field whose value becomes the URL parameter (e.g. `slug`, `id`).                        |
| `filter`              | Optional `{ field, operator, value }` conditions limiting which records generate pages. |

```yaml
pages:
  - name: Blog Post
    path: /blog/:slug
    collection:
      table: posts
      slugField: slug
      filter:
        - { field: published, operator: eq, value: true }
    rss: { limit: 20 }
    components:
      - { type: text, tag: h1, content: '$record.title' }
      - { type: text, content: '$record.body', props: { format: markdown } }
```

A request to `/blog/123` that does not match any record returns a `404`.

## Markdown Pages

Render a whole page from markdown — either inline or from a file — with frontmatter, layout, and an auto-generated table of contents.

| `markdown` property | Description                                                                                                      |
| ------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `content`           | Inline markdown string.                                                                                          |
| `file`              | Path to a markdown file (e.g. `content/docs.md`), resolved from project root. Mutually exclusive with `content`. |
| `layout`            | Wrapper style: `prose` (default), `docs`, `full`, or `none`.                                                     |
| `toc`               | Table-of-contents config — `true` for defaults, or `{ maxDepth, position }` (`inline` or `sidebar`).             |

YAML frontmatter (between `---` delimiters) is parsed and exposed as `$frontmatter.*` in `meta` and sibling properties. Markdown HTML is sanitized to prevent XSS (consistent with the `text`/`alert` content components).

```yaml
pages:
  - name: Docs Home
    path: /docs
    markdown:
      file: content/docs/home.md
      layout: docs
      toc: { maxDepth: 3, position: sidebar }
```

For the `contentDir` collection (one page per markdown file in a directory, with a derived sidebar), use a `content` component with a `contentDir` source:

| `contentDir` property | Description                                                                    |
| --------------------- | ------------------------------------------------------------------------------ |
| `directory`           | Directory containing markdown content files.                                   |
| `slugFrom`            | Derive URL slug from `filename` or `filepath`.                                 |
| `include`             | Glob pattern to filter files (e.g. `*.md`).                                    |
| `sort`                | `{ field, order }` — sort by a frontmatter field (e.g. `date`, `desc`).        |
| `filter`              | Filter conditions on frontmatter fields.                                       |
| `nav`                 | Sidebar config derived from the collection: `{ enabled, groupBy, labelFrom }`. |

## Layouts & Sidebars

The `layout` property wraps the page body in named sections. The most common is a data-bound `sidebar` rendered inside the page `<aside>`.

| Sidebar section property | Description                                                                   |
| ------------------------ | ----------------------------------------------------------------------------- |
| `dataSource`             | Binds entries to a table with `{ table, filter, sort }`.                      |
| `label`                  | Per-record label expression (supports `$record.<field>`).                     |
| `href`                   | Per-record anchor href (supports `$record.<field>`).                          |
| `archivedField`          | Field whose truthy value hides an entry from the sidebar.                     |
| `activeIndicator`        | Highlights the entry matching the active scope (e.g. tenant-switcher cookie). |

A scoped sidebar bound to `$currentUser.assignments.<table>` renders one entry per assigned record; a global admin (`isUnrestricted=true`) sees all records.

## Access Control

The `access` property gates a page:

| Form                                                 | Meaning                                                    |
| ---------------------------------------------------- | ---------------------------------------------------------- |
| `'all'`                                              | Everyone, including unauthenticated visitors (default).    |
| `'authenticated'`                                    | Any logged-in user.                                        |
| `['admin', 'editor']`                                | Specific role names.                                       |
| `{ require: 'authenticated', redirectTo: '/login' }` | Redirect unauthorized users instead of returning an error. |

## Related Pages

- [Layout Components](/en/docs/layout-components) — structural building blocks.
- [Content Components](/en/docs/content-components) — text, code, callouts, accordions.
- [Data Components](/en/docs/data-components) — tables, lists, charts, KPIs bound to your data.
- [Form Controls](/en/docs/form-controls) — inputs, selects, pickers, toggles.
- [SEO & Metadata](/en/docs/seo-meta) — document head, social cards, structured data.
- [Interactivity & Scripts](/en/docs/interactivity-scripts) — actions, animations, auto-save.
- [Tables Overview](/en/docs/tables-overview) — the data models pages render.
- [Forms](/en/docs/forms-overview) — standalone form definitions.
- [Search](/en/docs/search-overview) — full-text and public search configuration.
- [Theme](/en/docs/theme) — design tokens consumed by component styling.
