# Templates and composition

URL: https://tuimark.dev/guide/composition

> Reuse markup in a Tuimark document - split it into files with include and fragment, repeat a piece with template and use, scope its ids, bind each copy to its own data with with, and read the diagnostics and tool output for what a copy produced.

A document that grows has two problems: it gets long, and the same few lines appear again and again. The current language (a `<tui>` without `version`) has a tool for each, and both are expanded when the document is read, so nothing about them exists at run time. The dump, the keymap, focus, and the events see the expanded document, as if you had written every copy by hand.

| You want | Use | Result |
|---|---|---|
| to split a long document by the pieces a person would name | [`<include>` and `<fragment>`](/guide/language#composing-a-document-from-files) | the contents of a file placed where the include stands |
| to repeat a piece, each time with its own data | `<template>` and `<use>` (this page) | a copy of the template at every `<use>`, with scoped ids and its data behind an alias |

The two combine: a fragment can hold templates, so a team keeps its form fields in one file and every document includes it. A pinned document (one that writes `version="1"`, `"2"`, or `"3"`) has none of these tags; they are `V001`, "requires a `<tui>` without version".

## A template and its uses [#a-template-and-its-uses]

A `<template id="…">` holds a piece of markup. It is never drawn by itself. Each `<use template="…"/>` places a copy of it where the `use` stands:

```tui
<tui>
  <style>
    .label { bold: true; }
    .invalid { color: red; }
  </style>
  <template id="field">
    <col>
      <text class="label" class:invalid="f.error">{f.label}</text>
      <input id="input" bind="f.value" placeholder="{f.hint}" on:submit="submit"/>
      <text class="invalid" if="f.error">{f.error}</text>
    </col>
  </template>
  <keymap>
    <bind keys="ctrl+s" action="save" label="save"/>
    <bind keys="ctrl+n" action="focus" to="#email__input" label="email"/>
  </keymap>
  <screen id="main" focus="#name__input">
    <col gap="1" pad="1">
      <text>Hello, {form.name.value}</text>
      <use id="name" template="field" with="form.name as f"/>
      <use id="email" template="field" with="form.email as f"/>
      <hints/>
    </col>
  </screen>
</tui>
```

`field` has a label, an input, and an error line, and the form uses it twice. Each `<use>` names its template, gives the copy an `id`, and says which data the copy reads with `with`. Both fields come out of the same markup:

```grid

 Hello,

 Name
 your name

 Email
 ada@
 not an email

 ctrl+s save  ctrl+n email
```

- **Where a template stands.** As a direct child of `<tui>` or `<screen>`, in the document or in a fragment it includes; anywhere else is `V001`. It may stand before or after the uses that name it. Its `id` is required (`V012`) and unique among templates (`V004`).
- **What it holds.** Any elements, one or several. Not `<tui>`, `<screen>`, `<style>`, `<keymap>`, `<bind>`, `<fragment>`, or another `<template>` at any depth (`V001`), and no loose text (`V013`: wrap it in a `<text>`). A template can hold `<use>` elements of other templates, so a template can build on a smaller one.
- **What a `<use>` takes.** `template` (required), `id`, `with`, `if`, `hidden`, and a static `class`. Any other attribute is `V002`, and the message says where it goes instead: on the template's element, or as a class. A `<use>` takes no content, because there are no slots (`V013`).
- **What a copy is.** The same elements as the template, built where the use stands, checked as if you had written them there. A `<use>` is not a node: it takes no space in the layout, and `to="#email"` naming one is `B005`.

The first `<use>` in the example is `name`, and the second is `email`. Type into the first field, move to the second with `ctrl+n`, type, submit, and save:

```grid

 Hello, Ada

 Name
 Ada

 Email
 ada@x
 not an email

 ctrl+s save  ctrl+n email
```

```term
$ tuimark play field.tui --data field.json --cols 40 --rows 12 --input "text:Ada ctrl+n text:x enter ctrl+s"
4 submit email__input {} "ada@x"
5 save email__input {} "ada@x"
```

The heading reads `Hello, Ada` because the first copy's input wrote what you typed to `form.name.value`. The events say which copy fired them: `email__input`. Both of those follow from the two sections below.

## Scoped ids [#scoped-ids]

Two copies of one template cannot both have an input called `input`, so a copy's ids are prefixed with the id of its use and two underscores: the input of `<use id="email">` is `email__input`. This is the same `instance__part` shape the [kit](/guide/kit#conventions) uses for its ids, and it is what your own references use:

```term
$ tuimark dump field.tui --data field.json --cols 40 --rows 12
=== nodes (those with an id) ===
main          screen  40x12 @(0,0)
name__input   input   38x1 @(1,4) focus
email__input  input   38x1 @(1,7)
```

- **Outside the copy, write the scoped id.** The keymap row `<bind keys="ctrl+n" action="focus" to="#email__input"/>`, the screen's `focus="#name__input"`, a stylesheet rule `#email__input { … }`, and `play`'s `focus:#email__input` all name the copy's element. The host sees the scoped id too: the `source` of an event is `email__input`, and a host that routes by the part before the last `__` gets `email`.
- **Inside the copy, write the id as the template has it.** In a template, `focus="#no"` on a modal means the `no` button of the same copy, and each copy resolves it to its own: `del__no` for `<use id="del">`.
- **A reference to the unscoped id from outside is `B005`**, and the message names the one you want:

```tui
<tui>
  <template id="confirm">
    <modal id="dlg" open="c.open">
      <button id="no" label="No" on:click="no"/>
    </modal>
  </template>
  <keymap>
    <bind keys="n" action="focus" to="#no"/>
  </keymap>
  <screen id="main">
    <use id="del" template="confirm" with="ui.del as c"/>
  </screen>
</tui>
```

```term
$ tuimark validate ref-bad.tui
error B005 ref-bad.tui:8:5 /keymap/bind to="#no" refers to an id that does not exist; ids in a <template> are scoped by their <use>: #del__no
```

- **A use needs an `id` when its template has ids** (`V012`: the message lists them and the scoped form they take). A template with no ids can be used without one.
- **Nesting adds a prefix.** A template that uses another one scopes the inner ids by both uses: `billing__street__input` below.
- **A use's id is an id of the document**, so it must not repeat another (`V004`). A copy's ids never clash with another copy's.

A confirmation dialog is a good template, because its ids, the modal's `focus`, and its keys all stay inside the copy. Here the keymap row reaches the copy's modal by its scoped id, and `y`, `tab`, and `enter` act on it:

```tui
<tui>
  <template id="confirm">
    <modal id="dlg" open="c.open" focus="#no">
      <text>{c.question}</text>
      <row height="1" gap="1">
        <button id="yes" label="Yes" on:click="yes"/>
        <button id="no" label="No" on:click="no"/>
      </row>
    </modal>
  </template>
  <keymap>
    <bind keys="y" action="yes_pressed" when="#del__dlg" label="yes"/>
  </keymap>
  <screen id="main">
    <button id="open" label="Delete…" on:click="ask"/>
    <use id="del" template="confirm" with="ui.del as c"/>
  </screen>
</tui>
```

```term
$ tuimark play confirm.tui --data confirm.json --cols 30 --rows 8 --input "y tab enter"
1 yes_pressed del__no {} null
3 yes del__yes {} null
```

The `y` row fired with `del__no` as the source, the button the modal's `focus="#no"` selected; then `tab` and `enter` clicked `del__yes`. Pressing `esc` would close the modal, because `open="c.open"` is a path the runtime can write through the alias.

## What `with` does [#what-with-does]

`with="path as alias"` makes `alias` stand for `path` inside the copy. Every path in the copy that starts with the alias goes to that path in the store: `{f.label}` reads `form.email.label`, and `bind="f.value"` reads and **writes** `form.email.value`. That is why the typed text above reached `form.name.value`. Nothing is copied; the alias is a name for the path, so an input in a copy edits the same data a `{form.name.value}` anywhere else shows.

- **Several clauses** are separated by exactly a comma and a space: `with="form.one as x, form.two as y"`. Anything else is `V011`, as is an alias written twice in one `with`.
- **The target may not exist yet.** An input in the copy creates the path when you type. The use reports one `B003` for the missing path, and nothing more from the copy (see [a missing `with` path](#a-missing-with-path-and-optional-flags)).
- **Nested uses compose.** In `parts/forms.tui` below, `address` reads `a.street` and passes it on as `f` to `field`; the input ends up bound to `order.billing.street.value`.
- **A copy sees the aliases in scope where its use stands.** A use inside a list row or an `each` container can read the row's alias without being given it, and a `with` path can start with it: `with="j.status as s"`. The template then depends on where it is used, so give a reusable template a `with` for everything it reads.
- **An inner `each` can reuse the name of a use-site alias.** In the template, `each="g.items as r"` shadows the `r` of the surrounding list while the copy is built, and `g` still reads through `with="r.group as g"`. An inner `each` alias that repeats a `with` alias, though, is `V011` at that element. The copy is still placed.

### Templates in a fragment [#templates-in-a-fragment]

The two files of this example are the usual split. `parts/forms.tui` holds the templates; the document includes it and uses them twice:

```tui tab="app.tui"
<tui>
  <include src="parts/forms.tui"/>
  <screen id="main" focus="#billing__street__input">
    <col gap="1" pad="1">
      <use id="billing" template="address" with="order.billing as a"/>
      <use id="shipping" template="address" with="order.shipping as a" if="order.ship_elsewhere"/>
    </col>
  </screen>
</tui>
```

```tui tab="parts/forms.tui"
<fragment>
  <template id="field">
    <col>
      <text>{f.label}</text>
      <input id="input" bind="f.value"/>
    </col>
  </template>
  <template id="address">
    <box title="{a.title}" border="rounded">
      <use id="street" template="field" with="a.street as f"/>
      <use id="zip" template="field" with="a.zip as f"/>
    </box>
  </template>
</fragment>
```

```grid

 ╭─ Billing ────────────────────╮
 │Street                        │
 │1 Main St                     │
 │ZIP                           │
 │94105                         │
 ╰──────────────────────────────╯

 ╭─ Shipping ───────────────────╮
 │Street                        │
 │                              │
 │ZIP                           │
 │                              │
 ╰──────────────────────────────╯

```

```term
$ tuimark dump app.tui --data data.json --cols 34 --rows 16
=== nodes (those with an id) ===
main                     screen  34x16 @(0,0)
billing__street__input   input   30x1 @(2,3) focus
billing__zip__input      input   30x1 @(2,5)
shipping__street__input  input   30x1 @(2,10)
shipping__zip__input     input   30x1 @(2,12)
```

`shipping` has an `if`, which is the next section. A fragment that holds templates is [checked on its own](/guide/tools#validate) with only the checks its elements give themselves, because the data and the uses are in the documents that include it.

```term
$ tuimark validate parts/forms.tui
ok (fragment checked on its own)
```

## Guards and classes on a use [#guards-and-classes-on-a-use]

`if` and `hidden` on a `<use>` decide whether its copy exists in the frame, and they are read **where the use stands**: the `with` of the same use is not in scope for them (`if="s.urgent"` would read a path the use itself defines, which is `B002`), but an `each` alias is. The same use in a list row is decided once per row.

```tui
<tui>
  <style>
    .badge { reverse: true; }
    .hot { bold: true; }
  </style>
  <template id="badge">
    <text class="badge" class:hot="s.urgent">{s.label}</text>
  </template>
  <screen id="main" focus="#jobs">
    <list id="jobs" each="jobs as j" key="j.id">
      <item>
        <row gap="1">
          <text>{j.name}</text>
          <use template="badge" with="j.status as s" if="show_badges" class="cell"/>
        </row>
      </item>
    </list>
  </screen>
</tui>
```

The badge exists only while `show_badges` is truthy. A copy that is not placed has no ids, no focus, and no events, as if the use were not written:

```grid
build
deploy
lint
```

```grid
build ok
deploy failed
lint skipped
```

- **Per placement.** The guard of a use in a list `<item>`, in the template of a container `each`, or in a table's row (below) is evaluated for each row, with the row's alias in scope. A guard whose path is missing is one `B002` at the use, not one per row.
- **A static `class`** on a use is added to every top-level element of the copy, after the classes the template wrote and before its `class:NAME` guards. Style it like any class:

```jsonc
// $ tuimark play rows.tui --data rows.json --cols 24 --rows 3 --input set:show_badges=true --format json
// excerpt: the nodes that have classes
[
  {"tag":"text","x":6,"y":0,"classes":["badge","cell"]},
  {"tag":"text","x":7,"y":1,"classes":["badge","cell","hot"]},
  {"tag":"text","x":5,"y":2,"classes":["badge","cell"]}
]
```

  The `badge` comes from the template, `cell` from the use, and `hot` from the template's `class:hot="s.urgent"` guard, true for the `deploy` row only.

### Tables [#tables]

A `<column>` holds its cell as text and cannot hold a `<use>` (`V016`). To reuse a column, make the whole `<column>` the template, and put the `<use>` where the column would stand, directly in the `<table>`. The template's `<item>` row template can be placed the same way.

```tui
<tui>
  <style>
    .hot { bold: true; }
  </style>
  <template id="status">
    <column title="Status" width="8" class:hot="s.urgent">{s.label}</column>
  </template>
  <screen id="main" focus="#jobs">
    <table id="jobs" each="jobs as j" key="j.id" height="4">
      <column title="Job" width="1fr">{j.name}</column>
      <use template="status" with="j.status as s" if="show_status"/>
    </table>
  </screen>
</tui>
```

```grid
Job             Status
build           ok
deploy          failed
lint            skipped
```

A `with` path that starts with the table's row alias (`j.status as s`) is read for every row. The use's `if` and `hidden` stay per table: setting `show_status` to false takes the column away for all rows, header included:

```grid
Job
build
deploy
lint
```

## Seeing what a copy produced [#seeing-what-a-copy-produced]

The expanded document is what every tool shows, so a copy is checked the way any element is. Three places tell you where it came from.

**The dump.** A copy's nodes appear in the node list with their scoped ids, as in the lists above. `tuimark play` and `dump` need no special flag.

**`inspect`.** Besides the cascade, `tuimark inspect` ends with the element a node was built from and the uses and includes that placed it, innermost first:

```term
$ tuimark inspect app.tui --data data.json --cols 34 --rows 16 --id shipping__zip__input
…
source parts/forms.tui:5:7
via <use id="shipping__zip" template="field"> parts/forms.tui:11:7
via <use id="shipping" template="address"> app.tui:6:7
```

The input `shipping__zip__input` was written at `parts/forms.tui:5:7`, placed by the `zip` use inside `address` (line 11), which the `shipping` use placed (`app.tui`, line 6). With `--json` the same information is the `source` member:

```jsonc
// $ tuimark inspect field.tui --data field.json --cols 40 --rows 12 --id email__input --json
// excerpt: "source"
{
  "source": {
    "file": "field.tui",
    "line": 9,
    "col": 7,
    "via": [
      {
        "use": "email",
        "template": "field",
        "file": "field.tui",
        "line": 21,
        "col": 7
      }
    ]
  }
}
```

A node the document writes itself has `"via": []`, and a document that writes `version` has no `source` at all. A use without an `id` is listed as `<use template="…">`.

**`ir`.** `tuimark ir` keeps the composition as written: a `use` node holds the copy it placed, in the template's own words (`f.value`, `{f.label}`), with the scoped `id` and a `from` member, `FILE:LINE` of the element the node came from. Read the aliases through the `with` of the enclosing `use`:

```jsonc
// $ tuimark ir field.tui
// excerpt: the <use id="email"> node and what it placed
{
  "kind": "use",
  "id": "email",
  "attrs": {
    "template": "field",
    "with": "form.email as f"
  },
  "children": [
    {
      "kind": "col",
      "from": "field.tui:7",
      "children": [
        {
          "kind": "text",
          "classes": [
            "label"
          ],
          "attrs": {
            "class:invalid": "f.error"
          },
          "text": "{f.label}",
          "from": "field.tui:8"
        },
        {
          "kind": "input",
          "id": "email__input",
          "attrs": {
            "placeholder": "{f.hint}"
          },
          "bind": "f.value",
          "from": "field.tui:9"
        },
        {
          "kind": "text",
          "classes": [
            "invalid"
          ],
          "if": "f.error",
          "text": "{f.error}",
          "from": "field.tui:10"
        }
      ]
    }
  ]
}
```

`from` is on every node a use or an include placed, and absent on a node the document wrote in its own file.

## Diagnostics [#diagnostics]

The codes a template can raise, with the page's examples where there is one. The [diagnostics reference](/reference/diagnostics) has the full text.

| Code | When |
|---|---|
| `V019` | a `<use>` without `template`, or one that names no template; or one that closes a [cycle](#cycles) |
| `V021` | the [limits](#limits): elements, source bytes, nesting depth |
| `V011` | a `with` that is malformed, repeats an alias, or uses one already in scope; an inner `each` alias equal to a `with` alias |
| `V012` | a `<template>` without `id`; a `<use>` without `id` whose template has ids |
| `V013` | text directly in a `<template>`; content in a `<use>` |
| `V001`, `V002`, `V004` | a template in the wrong place; an attribute a `<use>` does not take; a duplicate template or use id |
| `B002`, `B003` | a missing `if`/`hidden` path at a use; a [missing `with` path](#a-missing-with-path-and-optional-flags) or a missing path in a copy |
| `B005` | a `to=`, `when=`, or `focus=` that names a use, or names an id only the template writes |

### Cycles [#cycles]

A template that reaches itself through the uses in its body would never stop expanding, so each use on the cycle is `V019`, and none of them expands. A reference to a template that does not exist is `V019` too:

```tui
<tui>
  <template id="menu">
    <col>
      <text>menu</text>
      <use template="submenu"/>
    </col>
  </template>
  <template id="submenu"><use template="menu"/></template>
  <template id="self"><use template="self"/></template>
  <screen id="main">
    <use template="menu"/>
    <use template="nope"/>
  </screen>
</tui>
```

```term
$ tuimark validate cycle.tui
error V019 cycle.tui:5:7 /template/col/use <use template="submenu"> in <template id="menu"> makes a cycle of templates: menu → submenu → menu
error V019 cycle.tui:8:26 /template/use <use template="menu"> in <template id="submenu"> makes a cycle of templates: submenu → menu → submenu
error V019 cycle.tui:9:23 /template/use <use template="self"> in <template id="self"> makes a cycle of templates: self → self
error V019 cycle.tui:12:5 /screen/use <use template="nope"> names no <template>
```

Each message names a simple cycle through the use, starting from its own template, so the one you read is the loop that use closes. A long one is cut: up to 8 templates are named whole, and a longer cycle shows its first 8, then `… (N more)`, then the template it returns to. A cycle of ten templates reports ten uses, each starting at its own template:

```term
$ tuimark validate long-cycle.tui
error V019 long-cycle.tui:2:21 /template/use <use template="t1"> in <template id="t0"> makes a cycle of templates: t0 → t1 → t2 → t3 → t4 → t5 → t6 → t7 → … (2 more) → t0
… (9 more lines)
```

A cycle is reported whether or not any use reaches it. One that only copies meet (possible once the template definitions' own `V021` has stopped a body) is reported once, at the use that closes it, however many copies meet it.

### Limits [#limits]

Because a copy of a copy of a copy grows fast, expansion has a budget, shared with `<include>`. A document that would pass any of these is `V021`:

- **100000 elements** inserted by includes and uses, counted once per copy, at every depth;
- **16 MiB of placed source**, counting the fragments and templates copied, the scoped-id prefixes, and the `with` paths substituted into each copy;
- **256 levels** of nesting in the resulting tree, counting each `<include>` and `<use>` as a level.

The use that would go over inserts nothing, and no later include or use expands, so the rest of the document is still reported. Five uses of a template in each of seven templates, one inside another, is 5⁷ leaves:

```tui
<tui>
  <template id="t0"><use template="t1"/><use template="t1"/><use template="t1"/><use template="t1"/><use template="t1"/></template>
  <template id="t1"><use template="t2"/><use template="t2"/><use template="t2"/><use template="t2"/><use template="t2"/></template>
  <template id="t2"><use template="t3"/><use template="t3"/><use template="t3"/><use template="t3"/><use template="t3"/></template>
  <template id="t3"><use template="t4"/><use template="t4"/><use template="t4"/><use template="t4"/><use template="t4"/></template>
  <template id="t4"><use template="t5"/><use template="t5"/><use template="t5"/><use template="t5"/><use template="t5"/></template>
  <template id="t5"><use template="t6"/><use template="t6"/><use template="t6"/><use template="t6"/><use template="t6"/></template>
  <template id="t6"><use template="t7"/><use template="t7"/><use template="t7"/><use template="t7"/><use template="t7"/></template>
  <template id="t7"><spacer/></template>
  <screen id="main"><use template="t0"/></screen>
</tui>
```

```term
$ tuimark validate fan.tui
error V021 fan.tui:8:81 /screen/use use template="t7" exceeds the expansion limit (100000 elements or 16 MiB of placed source): it inserts nothing, and no later include or use expands
```

The error is at the use that went over, `t7` in `t6`, with the line and column of that use. A fragment included inside a `<template>` has a budget of its own, so a template whose include would fan out is reported even when no use copies it: the message ends `exceeds the expansion limit for template definitions`, and the template is checked without that include.

### Messages about a copy [#messages-about-a-copy]

An element that a use placed is written once in the template and exists once per copy, so a diagnostic about it is reported at the template's line and has to say which copy it means. There are two forms.

**A path that went through a `with` alias** ends with the path it stands for and the use that gave it: `(P via <use …>)`. In the form below the template reads `f.help` and the use `email` made that `form.email.help`; the `phone` use has no `form.phone`, so the use is the problem, and the copy says nothing more:

```tui
<tui>
  <template id="field">
    <col>
      <text class:invalid="f.error">{f.label}</text>
      <input id="input" bind="f.value"/>
      <text if="f.error">{f.error}</text>
      <text>{f.help}</text>
    </col>
  </template>
  <screen id="main">
    <use id="email" template="field" with="form.email as f"/>
    <use id="phone" template="field" with="form.phone as f"/>
  </screen>
</tui>
```

```term
$ tuimark validate missing.tui --data missing.json
warning B003 missing.tui:7:7 /screen/col/text bind path "f.help" is missing (form.email.help via <use id="email">)
warning B003 missing.tui:12:5 /screen/use with path "form.phone" (alias f) is missing
ok
```

A use with an `id` is named by it (`<use id="email">`). A use without one is named by its template (`<use template="badge">`), and when the path starts with an `each` alias, which reads the same in every row, the message adds where the use is written, so you can find it: ` at FILE:LINE:COL`.

```term
$ tuimark validate rows.tui --data rows-bad.json
warning B003 rows.tui:7:5 /screen/list/item/row/text bind path "s.label" is missing (j.status.label via <use template="badge"> at rows.tui:14:11)
ok
```

**Any other diagnostic about a copy** (a `V012` at a copied box, a store flag that is missing) ends with `, placed by <use …> at FILE:LINE:COL`, naming the use that placed the element, and its file, line, and column. A use inside another template is named by its scoped id (`<use id="top__in">`), and its location is the line where it is written in the template. An element placed by an `<include>` ends with `, placed by <include> at FILE:LINE:COL` in the same way.

### A missing `with` path and optional flags [#a-missing-with-path-and-optional-flags]

- **A `with` path that is missing is one `B003` at the use**, a warning (an error under `--strict`), as above for `phone`. The copy's own paths are not reported, because each one would say the same thing, so you fix the one line. The copy is still placed, and an input in it still writes the path.
- **A flag in the copy is optional.** When the alias stands for an object, `if`, `hidden`, `disabled`, `open`, and `class:NAME` guards read through it are `null` if the member is missing, without a `B002`: `if="f.error"` is how a form field shows an error only when the host has written one, and `missing.tui` above does not report `f.error`. A `{path}` or a `bind` is still `B003` when missing. When the alias stands for something that is not an object, every flag reports.
- **A store flag is an ordinary one.** A path that does not start with an alias (`hidden="debug"`) is `B002` when missing, once per copy: `, placed by <use id="email"> at …`.

### Long ids and paths [#long-ids-and-paths]

A message quotes at most 64 bytes of an id or a path, cut at a character boundary and followed by `…`, so one very long name cannot make a diagnostic unreadable. Both the path in the copy and the path it stands for are cut, and so is a template name:

```term
$ tuimark validate long.tui --data long.json
warning B003 long.tui:3:5 /screen/text bind path "f.settings.profile.preferences.notifications.email.digest.freque…" is missing (user.settings.profile.preferences.notifications.email.digest.fre… via <use id="u">)
error V019 long.tui:7:5 /screen/use <use template="another_template_whose_name_is_longer_than_sixty_four_bytes_so_n…"> names no <template>
```

`--json` carries the message as printed. The full names are in the source.

## Tools and templates [#tools-and-templates]

- [`validate`, `fmt`, `inspect`, `run`, and `preview --watch`](/guide/tools#composition-in-the-tools) know about fragments and copies.
- [The language server](/guide/editors#what-the-language-server-does) checks a fragment through the documents that include it and follows `template=` and scoped ids across files.
- [`play` and `dump`](/guide/testing#documents-built-from-parts) in a test see the expanded document, so a golden does not change when you move a piece into a fragment, as long as the expansion is the same.
- The [kit](/guide/kit#templates-in-your-own-markup) is a fragment of templates: include `kit/kit.tui` once and copy its components with `<use>`.
