`duxt.sources` es una lista de entradas de fuente; `duxt.sourceOptions` dice
cómo se convierten en URL. Ambas se leen en tiempo de compilación. Qué generan y
por qué está en [Fuentes](/concepts/sources).

Los refs requieren un `repo` explícito, incluso para publicar otro ref de este
repositorio. Sin `repo`, la fuente lee el checkout local actual y rechaza `refs`
(incluido `latest`) y las sobrescrituras locales de `ref` por idioma.
`origin.repo` y `origin.ref` solo aportan enlaces de procedencia; no seleccionan
contenido. Un idioma con su propio `repo` explícito puede elegir su propio
`ref`. Para versiones locales, usa `version` en fuentes con carpetas distintas o
las `versions` basadas en archivos de una sección generada.

## Una entrada de fuente

| Campo     | Tipo                     | Notas                                                            |
| :-------- | :----------------------- | :---------------------------------------------------------------- |
| `path`    | `string`                 | Carpeta con el Markdown, relativa a la raíz del repositorio        |
| `repo`    | `string`                 | `owner/name` o una URL de git. **Omitido significa el checkout local** |
| `refs`    | lista de refs            | Refs a publicar como versiones; requieren un `repo` explícito |
| `releases` | `{ select, prereleases? }` | Descubrir tags de versión para publicarlos — véase abajo |
| `tagComponent` | `string`            | Publicar solo los tags `<name>@vX.Y.Z` de un paquete — véase [Tags por componente](#tags-por-componente) |
| `version` | `string`                 | La versión que esta fuente representa por sí misma |
| `label`   | texto                    | Mostrado en el selector y usado en la URL; por defecto, la ref     |
| `name`    | texto                    | Cómo **se llama** esta fuente donde el sitio la nombra. Solo visualización — véase abajo |
| `slug`    | `string`                 | El segmento de URL de esta fuente. **Declararlo es reclamarlo** — véase abajo |
| `status`  | estado                   | Ciclo de vida de cada versión que publica esta entrada             |
| `statusDefaults` | `{ latest?, branch?, tag? }` | Ciclo de vida por defecto según el tipo de ref |
| `origin`  | `{ repo, ref?, path? }`  | Dónde viven las páginas leídas del disco, para enlazar de vuelta   |
| `history` | `boolean`                | Leer el historial git de esta fuente                               |
| `content` | `boolean`                | `false` si la fuente solo contiene material generado |
| `exclude` | `{ drafts?, partials? }` | Globs por fuente para borradores y parciales |
| `flavor`  | `'tfplugindocs'`         | Interpretar el árbol Markdown como un dialecto compatible |
| `locales` | lista de locales         | Idiomas en los que está disponible esta fuente — véase abajo       |
| `generated` | lista de secciones      | Artefactos publicados como páginas junto al Markdown — ver debajo |

Dos campos son fáciles de confundir y caros de equivocar:

- **`repo` descarga, `origin` solo enlaza.** Nombrar tu propio repositorio en
  `repo` hace que la compilación clone el checkout en el que ya está.
- **`origin.path` es la carpeta en la forja.** Úsalo cuando la carpeta del
  disco es una copia —contenido copiado a un contexto de build o un checkout
  vecino leído mediante `../`— para que «Edit this page» abra `docs/…` y no la
  ruta de la copia. Las carpetas de idioma se mapean a través del `path` de la
  fuente, así que deben estar dentro de él.
- **`history` cuesta un clon completo.** Content clona un repositorio remoto con
  `--depth 1`, así que su checkout contiene un commit y cada archivo parece
  escrito por quien cortó la punta — datos erróneos, no datos ausentes.
  Activarlo completa el clon una vez. Una fuente leída del disco ya es un
  checkout completo y se lee de todos modos.

**`slug` reclama un segmento.** Normalmente una fuente solo recibe uno cuando la
lista nombra más de un repositorio — todo o nada, para el sitio entero. Una
fuente que escribe su propio `slug` se sirve bajo él de todas formas, y las que
no escriben ninguno se quedan donde están: es lo que permite que algo viva en
`/demo` junto a una documentación que conserva la raíz.


**`name` es un nombre; `label` y `slug` son direcciones.** El diálogo de
búsqueda rotula cada resultado con la fuente de la que procede, y antes de esta
clave solo podía deducirlo de la URL: una documentación servida en la raíz se
anunciaba como `/`, y una fuente cuyo segmento es una abreviatura, como `tf`.
`name` es solo visualización: no llega a ninguna colección, ni prefijo, ni
versión, ni al ranking — precisamente por eso puede ser prosa y puede
traducirse.

```ts
sources: [
  // Un registro de locales, porque el nombre es un sustantivo que se traduce.
  {
    repo: 'acme/docs',
    path: 'docs',
    name: { 'en-GB': 'Handbook', de: 'Handbuch', fr: 'Manuel' }
  },
  // Un literal simple, porque un nombre de producto es la misma palabra en todas partes.
  { repo: 'acme/terraform-provider-acme', path: 'docs', slug: 'tf', name: 'Terraform Provider' }
]
```

Sin declarar, el nombre recurre al propio segmento de la fuente (`demo` →
**Demo**) y después a `duxt.title`, que en un sitio sin título es la propia
etiqueta localizada **Documentación**. Conviene declararlo siempre que el
segmento sea una abreviatura. Dos fuentes distintas que acabarían con un mismo
nombre se distinguen automáticamente por su repositorio o su carpeta.

### Contenido, exclusiones y dialectos de fuente

`content: false` evita publicar páginas Markdown corrientes de la fuente, pero
mantiene activas sus declaraciones `generated`. `exclude.drafts` y
`exclude.partials` sustituyen los globs de esa fuente cuando un repositorio usa
otras convenciones.

`flavor: 'tfplugindocs'` interpreta los directorios, encabezados y categorías de
un árbol Markdown producido por tfplugindocs. Las páginas siguen siendo páginas
Content corrientes para búsqueda, versiones, locales y lectores automáticos.
Véase [Publicar documentación de un proveedor de Terraform](/guides/publish-terraform-provider-docs).

## Refs

Una cadena sola es una **rama**. Una etiqueta tiene que decirlo: git mantiene
ramas y etiquetas en espacios de nombres separados, y pedir una etiqueta bajo
`refs/heads` hace fallar la compilación con `Could not find refs/heads/…`.

```ts
refs: [
  'main',                                     // una rama
  { branch: 'next', status: 'upcoming' },     // la misma, con un ciclo de vida
  { tag: 'v2.0.0', label: 'v2' },             // una etiqueta
  'latest'                                    // la etiqueta semver más nueva, resuelta al compilar
]
```

`'latest'` está reservado. Una rama que de verdad se llame `latest` necesita la
forma `{ branch }`.

## Releases

`releases` descubre tags en lugar de mantener un historial largo en la
configuración. El descubrimiento es opt-in y siempre declara qué selecciona: no
hay un «todas las versiones» implícito porque las URL que permanecen accesibles
son una decisión del sitio.

```ts
{
  repo: 'acme/sdk',
  path: 'docs',
  releases: { select: 'minor' }
}
```

| `select`  | Publica                                           |
| :-------- | :------------------------------------------------ |
| `'all'`   | cada versión                                      |
| `'minor'` | la versión más reciente de cada línea minor        |
| `'major'` | la versión más reciente de cada línea major        |

Las preversiones quedan fuera salvo que `prereleases: true` las incluya. La
versión seleccionada más reciente es la predeterminada; una ref con
`default: true` o `sourceOptions.defaultRef` sigue teniendo prioridad.

El ciclo de vida no cambia: el estado de la fuente o `statusDefaults.tag` se
aplica a cada tag descubierto. No se deduce nada por la antigüedad de una
versión.

`refs` sigue disponible junto a `releases`. Una entrada para un tag descubierto
sustituye su etiqueta, estado, valor predeterminado y locales; cualquier otra se
publica a su lado.

```ts
{
  repo: 'acme/sdk',
  releases: { select: 'major' },
  refs: [
    { tag: 'v1.4.2', label: 'v1', status: 'deprecated' },
    { branch: 'main', status: 'upcoming' }
  ]
}
```

Una selección sin tag coincidente detiene la build e identifica la fuente y la
selección. Un repositorio ilegible se informa por separado como error de Git. La
misma distinción se aplica a `latest`.

### Tags por componente

Un monorepo que publica varios paquetes por separado etiqueta cada uno por su
**componente** — release-please escribe `duxt@v0.4.0` junto a
`duxt-typesense@v0.1.0`. Ambas formas son versiones: `latest`, `releases` y el
orden del selector leen `<name>@vX.Y.Z` igual que `vX.Y.Z`, y la etiqueta y el
segmento de URL muestran solo la versión — `v0.4.0`, nunca `duxt@v0.4.0`. La ref
conserva el tag completo, porque es el nombre que git conoce.

Si el repositorio etiqueta más de un paquete, «el tag más reciente» no significa
nada hasta decir de cuál. `tagComponent` nombra el paquete:

```ts
{
  repo: 'kirchDev/duxt',
  path: 'docs',
  tagComponent: 'duxt',
  refs: [{ tag: 'latest', default: true }]   // duxt@v…, nunca duxt-typesense@v…
}
```

**Los tags `vX.Y.Z` simples siguen contando**: son las versiones del paquete
anteriores a los tags por componente, y descartarlos despublicaría cada una.
Los tags de otro componente nunca cuentan. Sin `tagComponent`, todo tag que se
lea como versión es candidato, con prefijo o sin él.

## Locales

Omitido, la fuente tiene un idioma y una colección. Listado, cada entrada se
convierte en una colección propia.

```ts
locales: [
  'en-GB',                                              // el predeterminado: docs/ mismo
  'de',                                                 // docs/de/
  { locale: 'fr', path: 'translations/fr' },            // en otro sitio de este repositorio
  { locale: 'es', repo: 'acme/docs-es', path: 'docs' }  // otro repositorio
]
```

Una cadena es una carpeta dentro del `path` de la fuente. La forma de objeto
sobrescribe `path`, `repo` y `ref` solo para ese idioma — que es lo que permite
que una traducción viva en un repositorio propio, con sus propios responsables y
su propio calendario de publicación.

**El locale por defecto es el árbol de `path` mismo y no ocupa carpeta.** Cuál
es viene de `sourceOptions.defaultLocale`, y tiene que coincidir con
`i18n.defaultLocale` — la compilación falla si difieren, porque
`content.config.ts` resuelve las colecciones sin acceso a la configuración de
Nuxt.

Una ref puede llevar sus propios `locales`, sobrescribiendo los de la fuente
igual que hace `status`. Esa es la forma habitual: la versión actual está
traducida, las anteriores no.

```ts
refs: [
  { tag: 'v2.0.0' },                     // hereda los locales de la fuente
  { tag: 'v1.0.0', locales: ['en-GB'] }  // solo el original
]
```

Nombra una carpeta por **idioma** donde la región no aporte nada: `docs/pt/`
sirve tanto a `pt-PT` como a `pt-BR`, porque una página recae en su idioma base.
La misma regla que siguen los archivos de locale de la propia capa.

## Estado

`statusDefaults` define un ciclo de vida por tipo de ref cuando la propia ref no
lo indica: `latest` para el tag elegido por la entrada reservada, `branch` para
ramas y `tag` para tags explícitos o descubiertos. El estado explícito de una ref
siempre gana; el estado de la fuente es el fallback común.

```ts
statusDefaults: {
  latest: 'current',
  branch: 'upcoming',
  tag: 'deprecated'
}
```

| Valor        | Significa                                            |
| :----------- | :--------------------------------------------------- |
| `upcoming`   | Aún no publicada — todavía puede cambiar              |
| `current`    | La documentación que hay que leer                     |
| `maintained` | Más antigua, aún con soporte                          |
| `deprecated` | Más antigua, y el lector debería actualizar           |
| `eol`        | Muerta — se avisa, y fuera del sitemap                |

Lo que cada uno le cuesta a una página está en
[URL y versiones](/concepts/urls-and-versions).

## Secciones generadas

`generated` lista artefactos que no son Markdown y el tipo que lee cada uno para
convertirlo en páginas. Qué es el mecanismo, y las dos políticas que responde un
tipo, está en [Secciones generadas](/concepts/generated-sections); los campos de
debajo son los mismos sea cual sea el tipo que los lee.

| Campo        | Tipo                     | Notas                                                        |
| :----------- | :----------------------- | :------------------------------------------------------------ |
| `type`       | `string`                 | La clave de registro del tipo — `changelog`, `openapi`, `bruno`, el tuyo |
| `path`       | `string`                 | El artefacto, relativo a la raíz propia de la fuente           |
| `label`      | `string`                 | La entrada de la barra y — slugificada — el segmento de URL    |
| `slug`       | `string`                 | Sustituye al segmento que produciría la etiqueta               |
| `options`    | objeto                   | Los mandos que ofrece ese tipo; cada tipo valida los suyos     |
| `versions`   | lista de versiones       | Las versiones de este artefacto — véase abajo                  |
| `locales`    | `Record<string, string>` | Un artefacto por idioma, leído solo por un tipo `per-locale`   |
| `navigation` | colocación               | `'sections'` (por defecto), `'navigation'` o `false`           |
| `icon`       | `string`                 | Cae al icono propio del tipo                                   |

**`path` es una ruta y nunca una URL.** Para una fuente que Content clona es
relativa a la raíz de ese checkout, así que el artefacto viaja con la versión a la
que pertenece — una regla en ambas direcciones. Una ubicación arbitraria dejaría
traer un artefacto desde cualquier parte y reabriría la cuestión de la red en
tiempo de compilación que `sources` ya cerró.

**`label` es una cadena simple, no un texto traducido**, por la misma razón que lo
es la etiqueta de una versión: un texto traducido no es una URL estable.

### Una sección con versiones propias

Una versión suele ser un **checkout**: `refs` en la fuente publica cada sección
una vez por ref. Una API, en cambio, suele guardar `openapi/v1.yaml` junto a
`openapi/v2.yaml` en el mismo repositorio y versionarse por **archivo**. Sin
`versions` serían dos secciones independientes y dos entradas de navegación.

```ts [app/app.config.ts]
generated: [
  {
    type: 'openapi',
    label: 'API',
    path: 'openapi/v2.yaml',
    versions: [
      { version: 'v2', path: 'openapi/v2.yaml' },
      { version: 'v1', path: 'openapi/v1.yaml', status: 'deprecated' }
    ]
  }
]
```

| Campo     | Notas                                                             |
| :-------- | :---------------------------------------------------------------- |
| `version` | Se muestra en el selector y se usa en la URL                      |
| `path`    | El artefacto de la versión; por defecto, la ruta de la declaración |
| `locales` | Artefactos por locale para esta versión                            |
| `status`  | Ciclo de vida — `deprecated`, `eol`, `upcoming`                    |
| `default` | Se sirve sin segmento de versión; por defecto, la primera entrada  |

La predeterminada se sirve en `/api` y las demás bajo su segmento, como
`/v1/api`. El selector las ofrece igual que las refs de una fuente, con el aviso,
`noindex` y canonical de una versión que no es la actual.

Se declaran **juntas y no como dos fuentes** a propósito: solo las variantes
producidas por una misma declaración se ofrecen como versiones entre sí. Una
fuente por versión de API publicaría además dos veces el árbol de documentación.

No las combines **nunca con `refs` en la misma fuente**. Ambas formas reclaman el
mismo segmento de URL y la compilación rechaza la combinación. Un tipo `global`
también las rechaza porque publica una sola historia en una URL sin versión. Un
changelog no es global: se publica por versión y puede llevar `versions` igual
que una referencia de API.

### Qué versión es cuál

Tres cosas se llaman versión alrededor de una página de referencia, pero solo
dos pertenecen a duxt:

- **La versión de la URL y del selector** es una ref o un valor `version`
  declarado arriba. El distintivo muestra qué variante estás leyendo.
- **`duxt.version`** es la cadena propia del sitio. Solo aparece en el distintivo
  cuando no hay nada entre lo que cambiar.
- **`info.version` de un documento OpenAPI** es lo que el documento declara sobre
  la API descrita. Se muestra como **Versión de API** en la página de referencia,
  nunca en el distintivo del selector.

Los números suelen parecerse, pero siguen siendo hechos distintos; duxt no
deduce ninguno del otro.

`options` es opaco para todo salvo el tipo que lo lee — una granularidad significa
algo para un registro de cambios y nada para una referencia de API. Una clave que
el tipo no conoce hace fallar la compilación en vez de ignorarse, porque una
opción mal escrita es un sitio que en silencio no obtiene lo que configuró.


## Opciones de fuente

| Campo           | Por defecto        | Qué hace                                                  |
| :-------------- | :----------------- | :--------------------------------------------------------- |
| `showRepo`      | desactivado        | Fuerza un segmento de repositorio con un solo repositorio   |
| `showVersion`   | desactivado        | Fuerza un segmento de versión con una sola versión          |
| `defaultRef`    | la primera ref     | La ref servida sin prefijo de versión                       |
| `defaultLocale` | el primer locale   | El locale servido desde `path` mismo, sin carpeta           |

## El manifiesto resuelto

La compilación convierte la lista anterior en `duxt.resolvedSources`, y eso es
lo que lee el tema. `useDuxtCollection()` lo expone; cada entrada lleva el
nombre de la colección, el `prefix` de URL, `repo`, `version`, `name`,
`isDefault`,
`locale`, `isDefaultLocale`, `status`, el repositorio y la ref de los que
vinieron las páginas, y si se leyó su `history`.

El locale está deliberadamente ausente de `prefix`: i18n ya lo antepone a la
ruta, así que todos los idiomas de una fuente comparten prefijo y solo se
diferencian por la colección.

## Medios de documentación

Las imágenes generadas pertenecen a `docs/_assets/`. Las referencias son relativas al archivo Markdown: `docs/1.guides/1.demo.md` usa `../_assets/demo.gif`. El prefijo `/_assets/` indica la raíz de documentación de la fuente. La misma regla se aplica al atributo de imagen `dark`.

duxt publica automáticamente imágenes PNG, JPEG, GIF, SVG, WebP, AVIF, APNG e ICO, incluidas las fuentes remotas en su ref seleccionado. Las URL separan repositorio, raíz de documentación y ref; conservan los enlaces de página y el proveedor de imágenes. `_assets/` no se convierte en sección ni página. Las cintas, scripts, Dockerfiles y otras fuentes de captura no se publican.

Las imágenes sin idioma permanecen en `_assets/` compartido. Una página en `docs/de/` puede usar `../_assets/demo.gif`; una variante alemana producida explícitamente en `docs/de/_assets/` usa `_assets/demo.gif`. Las imágenes proceden del repositorio y ref de la página. Un repositorio de traducción puede compartir imágenes dentro de su checkout, pero no obtiene medios de otro repositorio automáticamente. Traduce el texto alternativo y los pies de imagen con la página.