Configuración
Cada clave bajo duxt en app.config.ts — qué controla y cuándo se lee.
Todo lo de abajo vive bajo duxt en tu app/app.config.ts. Cómo funciona la
combinación, y por qué los arrays reemplazan en lugar de añadirse, está en
Configuración.
Sitio
| Clave | Por defecto | Qué controla |
|---|---|---|
title | ninguno | El nombre en la barra de navegación y en el título SEO |
logo | ninguno | Un logotipo en lugar del par de icono y nombre — ver abajo |
version | ninguna | El distintivo junto a él |
organization | ninguna | Quién publica el sitio, para schema.org — ver abajo |
locales | los siete | Qué idiomas de la capa sirve este sitio |
breadcrumb | true | false quita el rastro sobre el título de la página |
pageIcon | ninguno | Icono para páginas sin uno propio — el de la sección gana |
packageManagers | pnpm, npm, yarn, bun | Qué gestores ofrece un bloque de comando, en ese orden |
requestSamples | siete de doce | Qué muestras de código ofrece el cliente de pruebas — ver Muestras de peticiones |
sampleLanguages | ninguna | Gramáticas de Shiki extra, para x-codeSamples en un lenguaje que ninguna muestra nombra |
poweredBy | activado | false quita la línea «Powered by duxt» del pie |
Comportamiento
| Clave | Por defecto | Efecto |
|---|---|---|
copy.models | ChatGPT, Claude | Destinos en orden de menú; la lista sustituye al valor inicial |
contributors.avatarUrl | plantilla de GitHub | {username} se sustituye por colaborador |
toc.depth | 3 | Encabezado más profundo del índice |
toc.scrollOffset | 96 | Línea de activación bajo el borde de la ventana |
search.fuzzy | 0.35, 3, 20 | Umbral Fuse, longitud mínima y límite |
search.recentPages | 5 | Páginas recientes; 0 oculta la lista |
openapi.exampleDepth | 6 | Profundidad máxima de ejemplos derivados |
openapi.schemaDepth | 8 | Profundidad máxima del árbol de esquema |
shortcuts.singleCharacter | true | Teclas globales ?, [ y ]; ⌘/Ctrl+K permanece |
analytics.track | ninguno | Callback independiente del proveedor por interacción |
export default defineAppConfig({
duxt: {
copy: {
models: [
{
label: 'Mi asistente',
icon: 'simple-icons:openai',
url: 'https://example.com/new?prompt='
}
]
},
contributors: {
avatarUrl: 'https://github.com/{username}.png?size=96'
},
toc: { depth: 4, scrollOffset: 112 },
search: {
fuzzy: { threshold: 0.3, minMatchCharLength: 3, limit: 15 },
recentPages: 8
},
openapi: { exampleDepth: 6, schemaDepth: 8 },
shortcuts: { singleCharacter: false }
}
})
Las listas sustituyen sus valores iniciales. Una lista copy.models vacía
elimina destinos externos, no las acciones de copiar y ver la fuente.
search.recentPages: 0 no guarda entradas nuevas. Las opciones fuzzy solo
afectan a las aproximaciones tras una búsqueda Content vacía. Sin callback de
analytics no se envía nada; consentimiento, proveedor y almacenamiento
pertenecen al sitio consumidor.
logo
| Campo | Tipo | Notas |
|---|---|---|
src | string | La marca. Sin valor queda el icono genérico junto a title |
srcDark | string | Se intercambia por CSS bajo la clase dark, no por script |
alt | texto | Recae en title |
Definir uno es Dale identidad a tu sitio.
organization
El nodo Organization que los buscadores y los resúmenes de IA leen para nombrar
una fuente. Ausente hasta que lo definas: duxt renderiza la documentación de
otros y no adivina de quién.
| Campo | Tipo | Notas |
|---|---|---|
name | texto | El nombre de quien publica. Sin él no se publica nada |
url | string | Su sitio. Recurre a site.url |
logo | string | Absoluto, o una ruta desde la raíz; cuadrado y de 112px o más |
Anuncios
Un aviso para todo el sitio: una versión, una migración o un mantenimiento. No se renderiza ni se reserva espacio hasta que escribas una entrada.
announcements: [
{
text: { 'en-GB': 'Version 2 is out.', 'es-ES': 'La versión 2 ya está disponible.' },
link: { label: 'Leer las notas', to: '/releases/v2' }
},
{
id: 'march-maintenance',
text: 'Mantenimiento programado el domingo desde las 09:00 UTC.',
placement: 'below-header',
startsAt: '2026-03-01T09:00:00Z',
endsAt: '2026-03-08T09:00:00Z'
}
],
announcementOptions: { maxVisible: 1 }
La lista se dibuja en orden: una versión y una incidencia son dos anuncios, y el final de uno no debe retirar el otro.
| Campo | Tipo | Notas |
|---|---|---|
text | texto | Literal, clave i18n o registro por locale |
link | enlace | Una acción; las demás pertenecen a la página enlazada |
placement | above-header, below-header o above-content | Ubicación; por defecto above-header |
startsAt | string | Inicio; cualquier valor que analice Date |
endsAt | string | Final |
id | string | Identidad de cierre; se deriva del contenido y enlace si falta |
Dónde se dibujan
| Ubicación | Lugar |
|---|---|
above-header | Ancho completo sobre la barra de navegación; es el valor inicial |
below-header | Ancho completo bajo la barra y sobre las barras laterales |
above-content | En la columna del documento, junto a avisos de versión e idioma |
above-content pertenece a la columna del documento, por lo que aparece en
páginas de documentación y no en una landing sin esa columna.
announcementOptions.maxVisible limita cuántos anuncios muestra a la vez cada
ubicación. Un número limita cada ubicación, un objeto las limita por
separado ({ 'above-header': 1 }), y null, una clave omitida o la ausencia de
maxVisible significa sin límite. Al cerrar el anuncio superior, el siguiente
ocupa su lugar.
Cuándo se muestran
startsAt y endsAt se evalúan en el navegador contra el reloj del lector.
El anuncio empieza y termina sin despliegue ni recarga. La ventana es
semiabierta: se muestra desde startsAt y hasta endsAt.
Incluye un offset cuando importe el instante exacto
(2026-03-01T09:00:00Z). Sin zona horaria se usa la hora local del lector. Una
fecha inválida se trata como ausente, para que un error tipográfico no esconda
el aviso silenciosamente.
Cierre
Un anuncio cerrado sigue cerrado durante la navegación, las recargas y los cambios de idioma. Se recuerda su identidad:
- con
id, exactamente esa cadena independiente del locale; cambiarla vuelve a mostrar el anuncio a todos, - sin
id, un valor derivado de todas las variantes detextylink; cambiar el texto crea un anuncio nuevo, reordenar claves de locale no.
Usa id cuando quieras corregir el texto sin volver a mostrarlo. Los cierres
solo viven en localStorage; las claves de anuncios eliminados se descartan.
Como el reloj y los cierres pertenecen al navegador, la franja se dibuja tras
la hidratación.
La superficie del componente está en DuxtAnnouncements.
Navegación y enlaces
Una entrada de sección es un enlace más un campo propio:
| Campo | Tipo | Notas |
|---|---|---|
pageIcon | string | Icono para las páginas de esta sección que no definen uno. Prevalece sobre duxt.pageIcon; el frontmatter de una página sigue ganando |
Útil donde las páginas no pueden llevar icono — el frontmatter de un ADR está
fijado en title, description, status y date, así que el registro de
decisiones se representaría sin ninguno.
| Clave | Por defecto | Qué controla |
|---|---|---|
navigation | una entrada | Enlaces de la barra; una entrada con children es un desplegable |
sections | vacío | La segunda fila de la barra — las partes de primer nivel |
links | vacío | Enlaces de icono a la derecha de la barra |
aside | solo el título | title y links bajo la tabla de contenidos |
footer | vacío | copyright y legal |
landing | una acción | La página en / |
La mayoría se entregan vacíos, por dos razones distintas. links,
aside.links, footer.legal, title, version y el texto de la página de
inicio nombran un proyecto concreto — un repositorio, una comunidad, un aviso
legal, un nombre, una publicación, una frase sobre lo que hace — y pertenecen a
quien gestiona el sitio. sections nombra las
partes de un árbol de documentación, y el árbol es tuyo: cuatro pestañas
apuntando a nombres de carpeta que la capa hubiera adivinado no llevarían a
ninguna parte. Defínelo cuando tu documentación tenga secciones; hasta entonces
la fila no se representa y la barra lateral muestra el árbol completo, que es la
forma correcta para una documentación sin secciones.
Una fila por fuente. Una entrada pertenece a la fuente bajo cuyo prefijo de
URL se encuentra, y la fila muestra las entradas de la fuente en la que está el
lector — así, un sitio con la documentación en la raíz y otra cosa en /demo
escribe una sola lista sections y cada área dibuja su parte de ella. Una
sección generada bajo un área (/demo/openapi) pertenece a esa área en lugar de ser
un área propia. Un sitio con una sola fuente tiene un área, cada entrada está
dentro, y la fila es exactamente la lista tal como se escribió.
La página de inicio
La página en / dibuja tres bandas, y cada una está ausente hasta que se define
su clave.
| Clave | Por defecto | Qué dibuja |
|---|---|---|
badge | ninguno | La píldora sobre el titular — texto, o un objeto badge |
headline | ninguno | El h1; recae en title |
description | ninguna | El párrafo bajo él, y la meta descripción de la página |
actions | una, «Lee la documentación» | Los botones del bloque principal; una acción sin to resuelve a la primera sección |
command | ninguno | Un comando de instalación copiable bajo los botones |
preview | ninguno | Una página de este sitio, incrustada en una ventana de navegador |
features | vacío | La rejilla de tarjetas |
command es una string simple, no texto: un comando de shell es igual en
todos los idiomas, y uno traducido por error es uno que no se ejecuta. La capa
no entrega ninguno — no sabe cómo se llama tu proyecto, por la misma razón por
la que links está vacío.
No hay llamada a la acción final, deliberadamente. Los botones del bloque principal son la llamada; repetirlos bajo una rejilla de tarjetas exige a un lector recién llegado decidir dos veces.
badge se entrega vacío por la misma razón que links: una píldora sobre el
titular dice algo del estado de un proyecto — «beta», «v2 ya está» — y la capa
no sabe nada del estado del tuyo. Una cadena es la forma corta; el objeto añade
icono, color y destino.
Campo de badge | Tipo | Notas |
|---|---|---|
label | texto | Obligatorio. {version} se sustituye por la version del sitio |
icon | string | Cualquier nombre de Iconify |
variant | string | default, secondary, outline, success, destructive |
to | string | Convierte toda la píldora en un enlace |
external | boolean | La pestaña nueva |
badge: {
label: '{version} publicada',
icon: 'lucide:rocket',
variant: 'success',
to: 'https://github.com/acme/sdk/releases/latest',
external: true
}
preview es una ventana viva, no una imagen. Incrusta una página de este
sitio en un marco de navegador que el lector puede desplazar, navegar y cuyo
tema puede cambiar sin salir de la página de inicio. El marco se monta solo
cuando la banda entra en el viewport, y nunca durante el renderizado en
servidor — un iframe en el HTML inicial es una segunda carga completa
compitiendo con la primera.
Campo de preview | Tipo | Notas |
|---|---|---|
to | string | La página a incrustar; por defecto, la primera sección |
height | string | Cualquier longitud CSS. Por defecto 32rem, 24rem bajo sm |
src | string | Una captura EN LUGAR de la página viva |
srcDark | string | Sirve el modo oscuro; sin él, src sirve ambos |
alt | texto | El texto alternativo y el nombre accesible del marco |
El marco vivo carga la aplicación una segunda vez. Un sitio que prefiera no
pagar eso define src y obtiene la misma ventana alrededor de una imagen fija.
Forma de un enlace
| Campo | Tipo | Notas |
|---|---|---|
label | texto | Obligatorio |
to | string | Una ruta de documentación se localiza; una URL no |
icon | string | Cualquier nombre de Iconify, p. ej. lucide:rocket |
description | texto | Se muestra en un desplegable de la barra |
external | boolean | La pestaña nueva y la flecha — nunca el enrutado |
children | DuxtLink[] | Convierte una entrada de barra en un desplegable |
variant | variante de botón | Solo landing.actions |
Todo campo marcado como texto admite un literal, una clave i18n o un registro por locale — véase Localización.
Fuentes
| Clave | Se lee en | Qué controla |
|---|---|---|
sources | tiempo de compilación | Las fuentes de documentación |
sourceOptions | tiempo de compilación | Cómo esas fuentes se convierten en prefijos |
versions | ejecución | Sobrescribe las versiones derivadas cuando necesitan etiquetas o descripciones |
Ambas claves de fuente tienen su propia página. locales
es la tercera clave de compilación: cambiar cualquiera de las tres exige
recompilar.
El feed
/rss.xml está vacío hasta que feed.path nombra una sección:
feed: { path: '/changelog', title: 'mi proyecto — publicaciones' }
Desactivado por defecto a propósito. Un feed es una lista de cosas que han
pasado, y una página de referencia editada no es un acontecimiento — un sitio
que publica cada edición como elemento enseña a sus lectores a darse de baja.
Los elementos se ordenan por el date propio de la página, recurriendo al
último commit que la tocó, y solo la versión predeterminada de cada fuente
contribuye, de modo que un changelog versionado no repite cada entrada una vez
por versión.
La sección a la que suele apuntar es un
historial de versiones, cuyas páginas llevan cada una su
date.
Generado, no escrito
| Clave | Escrito por | Contiene |
|---|---|---|
resolvedSources | la compilación | El manifiesto: qué colección sirve qué prefijo |
layerVersion | la compilación | La versión de duxt, para el pie |
layerRepository | la compilación | El repositorio de duxt, para el pie |
Definir cualquiera de los tres a mano se sobrescribe en la siguiente compilación.