Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / UI

[Composable] — presentational components in public pages

[Composable] component Card(...) { ... } — a composition-only component with no auth identity

Mark a presentational, composition-only component `[Composable]` so a public page can compose it without marking it `[AllowAnonymous]` itself. A composable component carries no auth identity — it inherits its render surface from whoever composes it — and it ships bundled with its parent, so an anonymous visitor never triggers a separate blocked fetch for it. The data path is unaffected: every query still gates on the queried entity.

stable1 example compiled by CIuisecuritycompositionattribute

Summary#

UI is secure by default: a component is protected unless you explicitly make it public with [[ui-authorize|[AllowAnonymous]]]. That works for entry points — routed pages and trees a client fetches directly. But a library of presentational components (a Card, a Hero, a NavBar) is composed inside pages and carries no data or identity of its own. Marking each one [AllowAnonymous] would be noise, and forgetting one would break an otherwise-public page.

[Composable] is the marker for exactly those components:

[Composable]
component Card(string title) {
  render { Box { Text(title); } }
}

A [Composable] component inherits its render surface from whoever composes it. A public page can render it, an anonymous visitor can receive it (bundled with the page), and you never mark it [AllowAnonymous].

Signature#

[Composable] component Card(...) { ... } — a composition-only component with no auth identity

Description#

[Composable] says one thing: "I am presentational and composition-only — I carry no auth identity." Two consequences follow, and one hard rule stays untouched.

  • It is anon-composable. A public ([AllowAnonymous]) page may compose a [Composable] component and server-render it inline; an anonymous client may receive its structure.
  • A public page composing an unmarked component is a COMPILE ERROR, naming the component and both attributes that would fix it. An anonymous visitor is never served the structure of a component that is neither [AllowAnonymous] nor [Composable] — so a page that composes one could not paint for the very visitors it was marked public for. The check follows composition all the way down: a [Composable] that itself composes an unmarked component is the same problem one hop further out, and the error says which path reaches it.
  • It ships bundled. When a page composes [Composable] components, they travel with the page's payload, so an anonymous visitor's browser never issues a separate request for each child (which would be blocked for a protected component). Composition is seamless and needs no per-child round-trip.
  • The data path never inherits (hard rule). [Composable] only concerns a component's structure. Every query a component runs is still gated on the queried entity's own rules, exactly as anywhere else — a composable component with no data of its own exposes nothing. See component.

Use [Composable] for presentational library components. Use [AllowAnonymous] for a page or a directly-fetched tree you intend to be public. They are independent: a component is neither by default (secure), and the two flags answer different questions ("is this a public entry point?" vs. "is this a presentational piece I compose?").

Examples#

A public page composing a composable card — no [AllowAnonymous] on Card needed:

[Composable]
component Card(string title) {
  render { Box { Text(title); } }
}

[Page("/")]
[AllowAnonymous]
component Home() {
  render {
    Stack(gap: 2) {
      Card(title: "Welcome");
      Card(title: "Get started");
    }
  }
}

See also#

Related

component

The one archetype for all UI: a bounded reactive unit — typed props, reactive members (fields, `live`…

page authorization (policies)

A `policy` names a reusable authorization predicate over the current user — e.g. `policy Admins => UserRole.Any(r =>…

Slot (child content)

A `Slot` marks where a component renders the content block its caller wrapped around it. Writing `Card { Text("hi"); }`…