Una ref se convierte en una versión. Apunta una fuente a etiquetas y cada una se
publica, con un segmento de versión en la URL y una entrada en el selector.

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.

## Pasos

::steps
1. **Enumera las refs.** Una cadena simple es una **rama**. Una etiqueta tiene
   que declararlo — git mantiene ambas en espacios de nombres separados, y pedir
   una etiqueta bajo `refs/heads` hace fallar la compilación.

   ```ts [app/app.config.ts]
   sources: [
     {
       repo: 'acme/api',
       path: 'docs',
       refs: [
         { branch: 'main', status: 'upcoming' },
         { tag: 'v2.0.0' },
         { tag: 'v1.4.0' },
         { tag: 'v0.9.0', status: 'eol' }
       ]
     }
   ],
   sourceOptions: { defaultRef: 'v2.0.0' }
   ```

2. **Nombra la predeterminada.** `defaultRef` es la ref que se sirve sin prefijo
   de versión y a la que se dirige a los buscadores. Sin definir es la primera
   de la lista — que rara vez es lo que quieres cuando la lista empieza por una
   rama.

3. **Declara el ciclo de vida donde no puede deducirse.** Semver ordena las
   etiquetas, así que «más antigua que la predeterminada» no necesita ayuda. Lo
   que no puede es situar una rama frente a una etiqueta: `main` es `upcoming`,
   y sin decirlo se le pide a su lector que actualice a una versión más antigua
   que la que está leyendo.

4. **Descubre versiones si no quieres editar la lista en cada publicación.**
   Elige cuánto historial seguirá siendo direccionable: todas las versiones, el
   último parche de cada línea minor o la última versión de cada línea major.

   ```ts
   releases: { select: 'minor' },
   refs: [{ branch: 'main', status: 'upcoming' }]
   ```

   `all`, `minor` y `major` son políticas de URL duraderas. Las preversiones
   quedan fuera salvo con `prereleases: true`. Para una única versión móvil,
   `'latest'` sigue disponible.

5. **Marca el requisito de versión de una página en el texto**, donde alguien
   que mira una versión no puede ver las demás:

   ```md
   ### Reintentos :since{version="v2.0.0"}
   ```

::

## La granularidad de una versión

El nombre es **una decisión del sitio, no del mecanismo**, y es la más importante
aquí: aparecerá en cada enlace a tu documentación.

**Una línea por versión, como rama.** Así lo hacen Laravel, Symfony y Django:
`11.x`, `10.x` y `9.x` son ramas que siguen avanzando; una publicación de parche
no cambia la URL.

```ts [app/app.config.ts]
sources: [
  {
    repo: 'acme/api',
    path: 'docs',
    refs: [
      { branch: '12.x', status: 'upcoming' },
      '11.x',
      { branch: '10.x', status: 'deprecated' },
      { branch: '9.x', status: 'eol' }
    ]
  }
],
sourceOptions: { defaultRef: '11.x' }
```

Una cadena simple **es** una rama; solo una etiqueta tiene que declararlo.

**Una línea por versión, desde etiquetas.** Si la publicación es una etiqueta
pero la URL no debe cambiar con cada parche, `label` le da otro nombre:

```ts
refs: [
  { tag: 'v2.4.1', label: 'v2' },
  { tag: 'v1.9.3', label: 'v1', status: 'deprecated' }
]
```

**Cada publicación como versión propia.** `{ tag: 'v2.4.1' }` sin etiqueta de
presentación. Cada una se puede citar para siempre y el selector crece una entrada
por publicación: lo adecuado para una especificación, pero no para un manual.

Las mismas políticas se pueden mantener desde etiquetas en vez de repetirlas en
la configuración:

```ts
// Cada publicación que debe poder citarse.
releases: { select: 'all' }

// O el parche más reciente de cada línea minor duradera.
releases: { select: 'minor' }

// O una publicación actual por cada línea major.
releases: { select: 'major' }
```

La publicación seleccionada más reciente es la predeterminada salvo que una ref
explícita con `default: true` o `sourceOptions.defaultRef` indique otra cosa. Una
selección que no coincide con ninguna etiqueta hace fallar la compilación; un
repositorio inaccesible se informa como error de Git, no como selección vacía.

La misma elección se aplica a una sección con versiones propias: `version: 'v2'`
o `version: '2.4.1'`, con el mismo compromiso. Un modelo y una decisión, tanto si
el contenido viene de una ref como de un archivo.

::callout{type="tip" title="Los nombres generales envejecen mejor"}
Un segmento de versión forma parte de todos los enlaces a tu documentación.
`v2` sobrevive a las próximas cuarenta publicaciones; `2.4.1` queda obsoleta el
día en que sale `2.4.2`.
::

## Cuando las versiones no son refs

Una versión suele ser un checkout. Hay dos formas habituales que no lo son:

**Documentación en carpetas.** `docs/v1` junto a `docs/v2` en un repositorio, sin
etiquetas. Cada fuente nombra su versión:

```ts [app/app.config.ts]
sources: [
  { path: 'docs/v2', version: 'v2' },
  { path: 'docs/v1', version: 'v1', status: 'deprecated' }
]
```

**Una API en archivos.** `openapi/v1.yaml` junto a `openapi/v2.yaml` es la forma
habitual de mantener una API. Las versiones pertenecen a la *sección*, no a la fuente:

```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' }
    ]
  }
]
```

Ambas producen lo mismo que las refs: un segmento en la URL, una entrada en el
selector, el aviso y el canonical. El selector se limita al artefacto que lees:
en `/api` ofrece las versiones de la API; en una página de texto, las de la
documentación.

::callout{type="warning" title="Una de las dos, nunca ambas"}
Una fuente que declara `refs` **y** `version`, o una sección con `versions` en una
fuente con refs, hace fallar la compilación: ambas reclaman el mismo segmento de
la URL. Consulta la lista completa de campos en [Fuentes](/reference/sources).
::

## Qué pasa con las versiones antiguas

Una versión no predeterminada lleva `noindex` y un `canonical` que apunta a la
misma página en la predeterminada, y una versión `eol` abandona el sitemap por
completo. Eso es lo que impide que un buscador ofrezca `v0.9.0` cuando el lector
quería la documentación de hoy — véase
[URL y versiones](/concepts/urls-and-versions).

## Lista de comprobación

- [ ] Cada etiqueta está escrita como `{ tag: … }`, no como cadena simple
- [ ] Los nombres de versión tienen la granularidad de las líneas de soporte del proyecto
- [ ] `defaultRef` nombra la versión en la que deben aterrizar los lectores
- [ ] Una rama de la lista lleva un `status` explícito
- [ ] El selector muestra todas las versiones, con distintivo en las muertas
- [ ] La página de una versión muerta no está en `/sitemap.xml`
- [ ] Si las versiones son carpetas o archivos en vez de refs, se usa exactamente
      uno de `refs`, `version` de una fuente y `versions` de una sección