# [Composable] — presentational components in public pages

> 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.

<!-- id: ui-composable · area: ui · stability: stable · html: https://osysharp.com/reference/ui/composable/ -->

## Summary        {#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:

```osy syntax
[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      {#signature}
```osy syntax
[Composable] component Card(...) { ... } — a composition-only component with no auth identity
```

## Description    {#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](https://osysharp.com/reference/ui/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       {#examples}
A public page composing a composable card — no `[AllowAnonymous]` on `Card` needed:

```osy title="a composable, and a page that composes it" test app=ui-composable
[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       {#see-also}
- [page authorization (policies)](https://osysharp.com/reference/ui/authorize/) — `[AllowAnonymous]` / `[Authorize]` for pages and entry points.
- [component](https://osysharp.com/reference/ui/component/) — declaring components and how composition works.
- [Slot (child content)](https://osysharp.com/reference/ui/slots/) — projecting child content into a composed component.
