> From the [Strife developer docs](https://strife.app/docs/reference/field-reference/fields.reference). Every page is listed in [llms.txt](https://strife.app/docs/llms.txt).

# fields.reference()

Reference to other Strife documents, scoped by target type(s). Not localizable.

Reference to other Strife documents. Maps to editor `{ name: 'str-related', type: 'related' }`. Not localizable — the content index never treats relations as per-locale scalars.

Stored as an array of `{ id, displayName }` — the `Infer<>` / write shape (`ContentRef[]`). At **read** time the content index projects each reference into the full target document, so [`strife typegen`](https://strife.app/docs/reference/cli/typegen.md) emits `Target[]` instead.

## Example

```ts
fields.reference({
  label: 'Author',
  to: 'author',
})

fields.reference({
  label: 'Related posts',
  to: ['article', 'video-post'],
  multiple: true,
})
```

## Options

| Option         | Type                          | Required | Description                                                                                                                                                                                                                                       |
| -------------- | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label`        | `string`                      | Yes      | Label shown to editors in Strife Studio.                                                                                                                                                                                                          |
| `to`           | `string \| readonly string[]` | Yes      | The `defineType` name(s) this reference may point to. Resolves to the editor's `allowedCollections` via the default collection rule (`toPlural(toPascalCase(name))`) and drives the generated read type (`Target[]`).                             |
| `description`  | `string`                      | No       | Tooltip shown to editors.                                                                                                                                                                                                                         |
| `searchable`   | `boolean`                     | No       | Include in the team's search index.                                                                                                                                                                                                               |
| `filterable`   | `boolean`                     | No       | Allow filtering content lists by this value.                                                                                                                                                                                                      |
| `protected`    | `boolean`                     | No       | Restrict editing to users with the appropriate permission.                                                                                                                                                                                        |
| `propertyName` | `string`                      | No       | Override the stored property name.                                                                                                                                                                                                                |
| `multiple`     | `boolean`                     | No       | Allow selecting more than one document in the editor (wire `multiSelect`). **Defaults to `false`** — always compiled explicitly, so omitting it means single-select. Does not change the read type; the index always returns an array either way. |

> [!NOTE]
> **Studio-built templates are a separate concern.** `fields.reference()` always compiles an explicit `multiSelect: true/false`, so anything pushed through `defineType`/`strife push` is safe by default. A Related field built by hand in Strife Studio can still end up with no `multiSelect` attribute saved at all, in which case the `str-related` editor component's own default (`multiSelect = true`) applies — that's a separate frontend gap, not yet fixed, unrelated to this DSL.

> [!NOTE]
> If a target `defineType` overrides its own `collection`, the derived `allowedCollections` on this field (a picker-UI hint only) won't match it — `strife typegen validate` flags this as a warning. The generated read type is correct either way; only the Studio picker's collection scoping is affected.

## Output type

Write shape: `ContentRef[]` (`{ id, displayName? }`). Generated read shape (via `strife typegen`): `Target[]`, the fully projected target document(s).

## See also

* [Related](https://strife.app/docs/reference/fields/related.md) — the same editor, documented from the Strife Studio UI side.
* [`fields.references()`](https://strife.app/docs/reference/field-reference/fields.references.md) — a sized list scoped by allowed template names instead of by collection.
