---
title: "YAML plugin"
description: "Handle `.yaml` and `.yml` files as data documents to query with `content.get`, `content.list`, and SQL."
canonical_url: "https://content.comark.dev/plugins/built-in/yaml"
---
# YAML plugin

> Handle \`.yaml\` and \`.yml\` files as data documents to query with \`content.get\`, \`content.list\`, and SQL.

`yaml` is the YAML counterpart of [`json`](https://content.comark.dev/plugins/built-in/json). Each `.yaml` / `.yml` file becomes a [`ContentFile`](https://content.comark.dev/reference/types/content#contentfiletdata-tmeta) whose `data` is the parsed YAML object and whose `nodes` are empty.

## Usage

```ts [content.ts]
import { comarkContent } from 'comark-content'
import fs from 'comark-content/sources/fs'
import yaml from 'comark-content/plugins/yaml'

const content = comarkContent({
  source: fs('./content'),
  plugins: [yaml()],
})
```

Given `content/config/site.yaml`:

```yaml [site.yaml]
name: Acme
tagline: "Build: faster"
theme: dark
```

```ts [query.ts]
const config = await content.get('/config/site')
config?.data  // { name: 'Acme', tagline: 'Build: faster', theme: 'dark' }
```

---

## API

The plugin exposes a single factory:

### `yaml(options?)`{lang="ts"}

Returns a [`ContentPlugin`](https://content.comark.dev/reference/types/plugins#contentplugin) that registers a parser for `.yaml` and `.yml` files. Each file becomes a `kind: 'document'` [`ContentFile`](https://content.comark.dev/reference/types/content#contentfiletdata-tmeta) whose `data` is the parsed YAML object and whose `nodes` are empty. Files that fail to parse, or that parse to an array (rather than an object), are handled according to [`onError`](#options-onerror) — by default they are dropped with a warning.

**Parameters:**

- `options?`: see [Options](#options).

**Returns:** [`ContentPlugin`](https://content.comark.dev/reference/types/plugins#contentplugin)

---

## Options

`yaml(options?)` mirrors the `json` plugin's options:

| Option                                    | Type                            | Default           | Description                                                      |
| ----------------------------------------- | ------------------------------- | ----------------- | ---------------------------------------------------------------- |
| [`listingFields`](#options-listingfields) | `string[]`                      | `undefined`       | `data` fields kept in listings for `.yaml` / `.yml` entries.     |
| [`onError`](#options-onerror)             | `'throw' \| 'warn' \| 'ignore'` | Content `onError` | How to react to a malformed or non-object `.yaml` / `.yml` file. |

### `listingFields`

By default a listing keeps a document's whole `data` object. Pass `listingFields` to limit which `data` keys are retained in [`content.list()`](https://content.comark.dev/reference/content/list) results for `.yaml` / `.yml` entries, forwarded to [`content.addListingFields()`](https://content.comark.dev/reference/content/add-listing-fields):

```ts [listing-fields.ts]
import yaml from 'comark-content/plugins/yaml'

yaml({
  listingFields: ['name', 'theme'],
})
```

**Default:** `undefined`

### `onError`

How the parser reacts when a `.yaml` / `.yml` file can't be parsed or isn't an object: `'warn'` logs and drops it, `'ignore'` drops it silently, `'throw'` aborts. Defaults to the Content-level [`onError`](https://content.comark.dev/reference/content/comark-content#options-onerror) (which defaults to `'warn'`).

```ts
yaml({ onError: 'throw' }) // fail fast on malformed YAML
```

**Default:** the Content instance `onError` option

---

## Read data

Each `.yaml` / `.yml` file resolves to a regular `kind: 'document'` [`ContentFile`](https://content.comark.dev/reference/types/content#contentfiletdata-tmeta) whose `data` is the parsed object, so the core content methods ([`content.get()`](https://content.comark.dev/reference/content/get), [`content.list()`](https://content.comark.dev/reference/content/list), [`content.stat()`](https://content.comark.dev/reference/content/stat), and [`content.navigation()`](https://content.comark.dev/reference/content/navigation)) treat them like any other document, and [`content.query()`](https://content.comark.dev/plugins/built-in/sql-query) indexes their flattened `data`.

```ts
const config = await content.get('/config/site')
config?.data.theme  // 'dark'
```

::warning
[`content.search()`](https://content.comark.dev/plugins/built-in/full-text-search) is the only method that skips YAML files. It only indexes parsed nodes, which data files don't have.
::

Both `.yaml` and `.yml` extensions are registered, sharing the same parser.

## Trim listings

When a source serves large YAML records, restrict listings to the fields you actually render:

```ts [content.ts]
const content = comarkContent({
  source: fs('./content'),
  plugins: [yaml({ listingFields: ['name', 'theme'] })],
})

await content.list()
//    → each YAML entry's data is trimmed to { name, theme }
```


## Sitemap

See the full [sitemap](https://content.comark.dev/sitemap.md) for all pages.
