Diseño y navegación
Añade páginas y secciones, personaliza logotipo, cabecera y pie, y compón la interfaz en root.tsx.
En esta página
Las opciones de build van en ardo.config.ts. Todo lo que rodea al contenido se compone con React en app/root.tsx. Normalmente bastan algunas tareas habituales; después viene la referencia.
Tareas habituales
Añadir una página
Crea un archivo Markdown o MDX bajo app/routes/. Su ruta determina la URL: app/routes/guide/install.mdx se sirve en /guide/install/. El servidor lo detecta al instante y aparece en la navegación y búsqueda.
---
title: Install
description: Add the package to your project.
---
# Install
Run the installer for your package manager.
title define la etiqueta de navegación y el título del navegador. Los archivos TSX de app/routes/ también crean páginas, pero la navegación generada solo enumera Markdown y MDX: enlaza las páginas TSX desde la cabecera u otra página.
Ordenar las páginas
Las páginas con order aparecen primero, por número ascendente. Las demás siguen el orden alfabético del título.
---
title: Install
order: 2
---
Agrupar páginas
Coloca las páginas relacionadas en una carpeta. Su index.mdx define la etiqueta, el orden y el estado inicial del grupo. También es la página propia del grupo.
---
title: Releases
order: 20
collapsed: true
---
# Releases
Sin índice, el nombre de la carpeta sirve de etiqueta. Opciones en Frontmatter.
Ocultar una página de la navegación
Define sidebar: false en el frontmatter. La página se sigue construyendo y continúa accesible por enlace.
Añadir una sección
Cada carpeta principal de app/routes/ crea una sección con pestaña, como guide/ o api-reference/. Los nombres conocidos (guide, reference, api, examples, adr) reciben etiqueta e icono; los demás conservan el nombre de carpeta. La pestaña abre el índice o la primera página.
Ordena las pestañas en ardo.config.ts:
import { defineArdoConfig } from "ardo/config"
export default defineArdoConfig({
title: "My Docs",
sidebar: { sectionOrder: ["guide", "reference", "api"] },
})
Para secciones manuales, consulta Secciones de navegación.
Añadir enlaces en la cabecera
Pasa ArdoHeader con enlaces. ArdoNavLink añade la base a to; href acepta cualquier URL. Coloca los enlaces sociales en ArdoHeaderActions:
import {
ArdoHeader,
ArdoHeaderActions,
ArdoNav,
ArdoNavLink,
ArdoRoot,
ArdoSocialLink,
} from "ardo/ui"
export default function Root() {
return (
<ArdoRoot>
<ArdoHeader>
<ArdoNav>
<ArdoNavLink to="/guide/getting-started">Guide</ArdoNavLink>
<ArdoNavLink href="https://github.com/example/project/releases">Releases</ArdoNavLink>
</ArdoNav>
<ArdoHeaderActions>
<ArdoSocialLink href="https://github.com/example/project" icon="github" />
</ArdoHeaderActions>
</ArdoHeader>
</ArdoRoot>
)
}
ArdoSocialLink incluye los iconos github, discord, linkedin, npm, twitter y youtube.
Cambiar logotipo y favicon
Importa los archivos y pásalos a ArdoRoot. Las huellas de Vite llevan el nuevo logotipo a los lectores en el siguiente despliegue:
import { ArdoRoot } from "ardo/ui"
import icon from "./assets/icon.svg"
import logo from "./assets/logo.svg"
export default function Root() {
return <ArdoRoot logo={logo} icon={icon} />
}
logo admite { light, dark } y appleTouchIcon un PNG de 180×180 para iOS. Sin icon, Ardo enlaza sus iconos de búho. Consulta Temas.
Cambiar el pie de página
Pasa ArdoFooter con tu texto:
import { ArdoFooter, ArdoRoot } from "ardo/ui"
export default function Root() {
return (
<ArdoRoot>
<ArdoFooter message="Released under the MIT License." copyright="© 2026 Example Co" />
</ArdoRoot>
)
}
Sin ArdoFooter, aparece el pie predeterminado; footer={false} en ArdoRoot lo oculta. Props en Pie de página.
Raíz mínima
<ArdoRoot /> proporciona cabecera con búsqueda y tema, navegación por carpeta principal y pie. La configuración y los estilos llegan desde las entradas de Ardo; root.tsx solo importa los componentes usados.
import { ArdoRoot } from "ardo/ui"
export default function Root() {
return <ArdoRoot />
}
Compón la navegación con React. Pasa ArdoHeader, ArdoSidebar y ArdoFooter como hijos o define header, sidebar o footer como false:
import {
ArdoGeneratedSidebar,
ArdoHeader,
ArdoNav,
ArdoNavLink,
ArdoRoot,
ArdoSidebar,
ArdoSidebarSection,
} from "ardo/ui"
export default function Root() {
return (
<ArdoRoot>
<ArdoHeader>
<ArdoNav>
<ArdoNavLink to="/guide/getting-started">Guide</ArdoNavLink>
</ArdoNav>
</ArdoHeader>
<ArdoSidebar>
<ArdoSidebarSection id="guide" label="Guide" to="/guide/getting-started">
<ArdoGeneratedSidebar section="guide" />
</ArdoSidebarSection>
</ArdoSidebar>
</ArdoRoot>
)
}
ArdoRoot gestiona providers, contenido y espacios JSX. Esta parte se hidrata en el navegador.
ArdoRoot
ArdoRoot recibe los ajustes del sitio como props y la interfaz como hijos.
| Prop | Tipo | Uso |
|---|---|---|
theme | ArdoThemeProps | Tonos, saturación, avisos, fuentes y tokens; consulta Temas. |
logo | string | { light: string; dark: string } | ReactElement | Logotipo de cabecera y menú, normalmente importado. |
icon | string | Favicon importado SVG o PNG. Predeterminado: búho. |
appleTouchIcon | string | PNG de 180×180 para iOS. |
header | ReactNode | false | Cabecera propia en lugar de ArdoHeader, o false para omitirla. |
sidebar | ReactNode | false | Navegación propia en lugar de ArdoSidebar, o false para omitirla. |
footer | ReactNode | false | Pie propio en lugar de ArdoFooter, o false para omitirlo. |
editLink | { pattern: string; text?: string } | Patrón de enlaces de edición Markdown. |
lastUpdated | { enabled?: boolean; text?: string; formatOptions?: Intl.DateTimeFormatOptions } | Visualización de la fecha de modificación. |
labels | ArdoLabelsInput | Reemplaza los textos de interfaz. |
scrollMode | "viewport" | "document" | Shell de viewport (predeterminado) o desplazamiento del documento. |
tocLabel | string | Etiqueta del índice. |
className | string | Reemplaza la clase de diseño. |
config | ArdoConfig | Configuración del sitio. Los puntos de entrada de Ardo la proporcionan desde ardo.config.ts; pásala explícitamente en pruebas y vistas previas. |
components | ArdoMDXComponents | Añade o reemplaza componentes Markdown y su wrapper. |
children | ReactNode | ArdoHeader, ArdoSidebar, ArdoFooter y sustituciones opcionales del contenido. |
Cabecera
ArdoHeader proporciona la cabecera adaptable. Coloca ArdoNav dentro y las acciones de la derecha en ArdoHeaderActions.
import { ArdoHeader, ArdoHeaderActions, ArdoNav, ArdoNavLink, ArdoSocialLink } from "ardo/ui"
import logo from "./assets/logo.svg"
;<ArdoHeader logo={logo} title="My Docs" searchPlaceholder="Search documentation...">
<ArdoNav>
<ArdoNavLink to="/guide/getting-started">Guide</ArdoNavLink>
<ArdoNavLink to="/api-reference">API</ArdoNavLink>
</ArdoNav>
<ArdoHeaderActions>
<ArdoSocialLink href="https://github.com/example/project" icon="github" />
</ArdoHeaderActions>
</ArdoHeader>
El logo pasado a ArdoRoot llega a la cabecera y al menú móvil, salvo que la cabecera defina su propio logo.
| Prop | Uso |
|---|---|
logo | URL o variantes { light, dark }. |
title | Título; predeterminado: config.title. |
search | "auto", "field", "icon" o false. Predeterminado: "auto". |
searchPlaceholder | Texto de ayuda de búsqueda. |
themeToggle | false oculta el selector de tema. Predeterminado: true. |
className | Reemplaza la clase de cabecera. |
Búsqueda en la cabecera
Con search="auto", decide el diseño:
- Las páginas de documentación muestran un campo central.
- Las páginas libres (
handle = { layout: "bare" }, incluido el inicio) muestran un icono para dar espacio al hero.
search="field" o search="icon" fija una presentación. Bajo 1024 px, el campo pasa a icono. ⌘K, o Ctrl+K en Windows y Linux, abre siempre la búsqueda.
Pantallas pequeñas
Bajo 1024 px, quedan menú, logotipo y búsqueda. El menú termina con los selectores de versión, idioma y tema y las ArdoHeaderActions, como enlaces sociales.
Controles de versión
Con versioning, el selector aparece al final de la navegación o en el pie de páginas libres. Las versiones antiguas muestran un aviso hacia la misma página de la última versión.
Tus diseños pueden colocar ArdoVersionSwitcher (select), ArdoVersionControl (con etiqueta) y ArdoVersionBanner (aviso). No muestran nada con menos de dos versiones.
En páginas libres, la cabecera comparte anchura con ArdoHero, ArdoFeatures y ArdoFooter. Los documentos mantienen una cabecera completa. Ajusta --ardo-layout-pageMaxWidth y usa vars.layout.pageMaxWidth para alinear tus secciones.
Secciones de navegación
La navegación izquierda combina barra de secciones y panel. Las props de ArdoSidebarSection definen la sección y sus hijos el panel.
import { ArdoGeneratedSidebar, ArdoSidebar, ArdoSidebarSection } from "ardo/ui"
import { BookOpen, Code } from "ardo/icons"
;<ArdoSidebar>
<ArdoSidebarSection
id="guide"
label="Guide"
to="/guide/getting-started"
icon={<BookOpen size={18} />}
>
<ArdoGeneratedSidebar section="guide" />
</ArdoSidebarSection>
<ArdoSidebarSection id="api-reference" label="API" to="/api-reference" icon={<Code size={18} />}>
<ArdoGeneratedSidebar section="api-reference" />
</ArdoSidebarSection>
</ArdoSidebar>
ArdoGeneratedSidebar muestra la navegación Markdown y API generada de una sección principal. Para navegación manual, combina enlaces y grupos:
<ArdoSidebarSection id="guide" label="Guide" to="/guide/getting-started">
<ArdoSidebarGroup title="Guide">
<ArdoSidebarLink to="/guide/getting-started">Getting Started</ArdoSidebarLink>
<ArdoSidebarLink to="/guide/configuration">Configuration</ArdoSidebarLink>
</ArdoSidebarGroup>
</ArdoSidebarSection>
Pie de página
Pasa ArdoFooter como hijo de ArdoRoot.
<ArdoFooter
sponsor={{ text: "Example Co", link: "https://example.com" }}
message="Released under the MIT License."
copyright="Copyright 2026 Example Co"
/>
Enlaces de edición y fecha de modificación
editLink y lastUpdated se aplican a documentos Markdown y MDX. El frontmatter puede desactivarlos con editLink: false o lastUpdated: false.
<ArdoRoot
editLink={{
pattern: "https://github.com/example/project/edit/main/docs/app/routes/:path",
text: "Edit this page on GitHub",
}}
lastUpdated={{
enabled: true,
text: "Last updated",
formatOptions: { dateStyle: "medium" },
}}
tocLabel="On this page"
>
{/* Header, sidebar, and footer here */}
</ArdoRoot>
:path recibe la ruta fuente relativa a app/routes o routesDir, incluida la extensión. Mantén el prefijo del repositorio y directorio fuente en el patrón. Los enlaces son opcionales.
Las fechas proceden del último commit Git. Descarga todo el historial en CI (fetch-depth: 0 con actions/checkout). Sin historial, se usa la fecha del archivo. El formato sigue el idioma activo y UTC salvo otra zona en formatOptions. Las API generadas desactivan enlaces y fechas; los contenidos materializados también, salvo activación explícita en el frontmatter con un patrón fuente adecuado.
Hasta 1280 px, el índice se despliega bajo el título y las acciones aparecen al final del artículo. Las pantallas grandes conservan el panel derecho.
Interfaz por ruta
Exporta handle para ocultar elementos por ruta:
export const handle = { layout: "bare", chrome: false }
chrome: false elimina cabecera y pie. layout: "bare" elimina navegación lateral y panel.
Rutas libres con interfaz propia
Usa export const handle = { layout: "bare", chrome: false } si la ruta gestiona su cabecera y pie. Ardo no reserva espacio ni enlace de salto adicional; márgenes, fondo y desbordamiento del contenido son tuyos. Proporciona un enlace de salto para teclado.
Las rutas libres con cabecera Ardo conservan su desplazamiento y enlace de salto. Los documentos mantienen el desplazamiento interno.
Reemplazar elementos de la interfaz
Si el CSS no basta, escribe tu componente React:
import { useArdoConfig } from "ardo/runtime"
export function MyHeader() {
const config = useArdoConfig()
return (
<header className="my-custom-header">
<h1>{config.title}</h1>
{/* Your custom header content */}
</header>
)
}
Pásalo a ArdoRoot conservando los demás elementos predeterminados:
import { ArdoRoot } from "ardo/ui"
import { MyHeader } from "./components/MyHeader"
export default function Root() {
return <ArdoRoot header={<MyHeader />} />
}
header, sidebar y footer aceptan elementos React, o false para omitir esa parte. Entre sus hijos, ArdoRoot solo reconoce ArdoHeader, ArdoSidebar y ArdoFooter de Ardo; cualquier otro reemplaza el contenido. Mantén ArdoRoot alrededor de los componentes: proporciona contexto a los hooks siguientes.
message y copyright renderizan contenido React y escapan las cadenas. Para HTML de confianza, usa trustedMessageHtml y trustedCopyrightHtml, nunca con contenido de usuarios o CMS.
Reutilizar búsqueda y navegación móvil
ArdoHeaderSearch y ArdoMobileNavigation de ardo/ui comparten diálogos, atajos y gestión de foco de la cabecera predeterminada. Úsalos en el espacio header de ArdoRoot para compartir providers.
import { useState } from "ardo/react"
import {
ArdoGeneratedSidebar,
ArdoHeaderSearch,
ArdoMobileNavigation,
ArdoRoot,
ArdoSidebar,
ArdoSidebarSection,
} from "ardo/ui"
function SiteHeader() {
const [menuOpen, setMenuOpen] = useState(false)
return (
<header className="site-header">
<a href="/">My project</a>
<ArdoMobileNavigation open={menuOpen} onOpenChange={setMenuOpen}>
<ArdoSidebar>
<ArdoSidebarSection id="guide" label="Guide" to="/guide/install/">
<ArdoGeneratedSidebar section="guide" />
</ArdoSidebarSection>
</ArdoSidebar>
</ArdoMobileNavigation>
<ArdoHeaderSearch variant="icon" onActivate={() => setMenuOpen(false)} />
</header>
)
}
export default function Root() {
return <ArdoRoot header={<SiteHeader />} scrollMode="document" />
}
Sin open, ArdoMobileNavigation gestiona su estado. nav, actions, logo, title y themeToggle ajustan el panel; label, trigger y className ajustan el botón visible bajo 1024 px. El estado controlado permite cerrar el menú antes de buscar. Escape cierra los diálogos y restaura el foco. ArdoHeaderSearch acepta variant="field" o variant="icon".
Personalizar componentes Markdown
Pasa components a ArdoRoot para añadir o reemplazar componentes. Los valores predeterminados siguen disponibles; la prop MDX explícita components de una página tiene prioridad y su layout MDX conserva el wrapper. Define el mapa y los componentes React fuera de la función raíz para mantener identidades estables.
import type { ReactNode } from "ardo/react"
import { useArdoPageData } from "ardo/runtime"
import { ArdoDocContent, ArdoRoot } from "ardo/ui"
function Article({ children }: { children: ReactNode }) {
const page = useArdoPageData()
return (
<ArdoDocContent
header={
<header className="article-hero">
<h1>{page?.title}</h1>
</header>
}
tocSource="dom"
>
{children}
</ArdoDocContent>
)
}
const components = { wrapper: Article }
export default function Root() {
return <ArdoRoot components={components} />
}
Reemplaza table, a, CodeBlock o registra nombres MDX. Un a propio debe conservar la gestión de rutas internas. Reemplazar CodeBlock también reemplaza copia y resaltado.
Espacios de artículo
ArdoDocContent y ArdoDocPage aceptan estos espacios React. Omítelos para mantener el valor predeterminado; false o null los oculta.
| Slot | Reemplaza |
|---|---|
header | Título y descripción. Permanecen migas y avisos de versión. |
outline | Índice compacto en el artículo. |
rail | Panel de escritorio con índice y acciones. |
footer | Acciones y enlaces anterior/siguiente. |
ArdoContent expone los mismos espacios header, outline y footer. Un outline explícito tiene prioridad sobre outline: false del frontmatter.
Detectar títulos de componentes
El índice usa metadatos Markdown por defecto. tocSource="dom" en ArdoDocContent o ArdoDocPage detecta los títulos de componentes tras hidratar. El HTML servidor y el primer render conservan el índice estático; después se siguen adiciones, eliminaciones y cambios.
Usa <ArdoTOC source="dom" scope="#article-body" /> para un índice independiente. scope es un selector CSS opcional del contenido. Si falta, Ardo lee .ardo-content-body dentro de #main-content, o el propio #main-content en una página personalizada. Ambos modos usan markdown.toc.level para los niveles de título. Se excluyen navegación, índice, títulos ocultos y subárboles marcados con data-ardo-toc="exclude". Marca así los ejemplos cuyos títulos no deban convertirse en secciones.
Mantén identificadores explícitos y únicos para enlaces duraderos. El modo DOM añade ardo-heading-N sin colisiones, pero dependiente del orden. No amplía la búsqueda del build, el sitemap ni los exports LLM. Escribe el contenido indexable en Markdown.
Hooks de ejecución
Los componentes leen el estado mediante hooks de ardo/runtime:
| Hook | Devuelve |
|---|---|
useArdoConfig() | Configuración del sitio desde ardo.config.ts, como title, description y base. |
useArdoSiteConfig() | Los ajustes editLink, lastUpdated, labels, logo y tocLabel pasados a ArdoRoot. |
useArdoSidebar() | Elementos de navegación de la sección actual. |
useArdoPageData() | En Markdown/MDX: título, frontmatter, índice y fuente. |
useArdoTOC() | Índice actual o lista vacía. |
useArdoPath() | Ruta de página sin base. |
useArdoLocale() | Idioma activo, también durante el render servidor. |
useArdoContext() | Configuración, navegación y página juntas. |
Enlace de edición desde los ajustes y la página actual:
import { useArdoPageData, useArdoSiteConfig } from "ardo/runtime"
function MyEditLink() {
const { editLink } = useArdoSiteConfig()
const page = useArdoPageData()
if (!editLink?.pattern || !page?.relativePath || page.frontmatter.editLink === false) {
return null
}
const sourcePath = page.relativePath.split("/").map(encodeURIComponent).join("/")
const href = editLink.pattern.replace(":path", sourcePath)
return <a href={href}>{editLink.text ?? "Edit this page"}</a>
}
findCurrentSidebarItem y getPrevNextLinks ayudan a reemplazar los enlaces anterior/siguiente:
import {
ArdoLink,
findCurrentSidebarItem,
getPrevNextLinks,
useArdoPageData,
useArdoPath,
useArdoSidebar,
} from "ardo/runtime"
function MyPrevNext() {
const pathname = useArdoPath()
const page = useArdoPageData()
const sidebar = useArdoSidebar()
if (!page) return null
const current = findCurrentSidebarItem(sidebar, pathname)
const { prev, next } = getPrevNextLinks(sidebar, pathname)
return (
<nav>
<span>{current?.text}</span>
{prev?.link && <ArdoLink to={prev.link}>{prev.text}</ArdoLink>}
{next?.link && <ArdoLink to={next.link}>{next.text}</ArdoLink>}
</nav>
)
}
ArdoLink añade la base y renderiza un <a>; cada clic carga la página prerrenderizada. ArdoProvider y ArdoSiteConfigProvider proporcionan ese contexto en pruebas y vistas aisladas.
Layout: el shell HTML
Ardo renderiza cada página en un shell HTML: <html>, <head> y <body>. Solo se renderiza en el servidor durante ardo dev y ardo build; la raíz interior se hidrata. Por defecto, ArdoRootLayout de ardo/ui añade codificación, viewport, script de tema, favicons, título, metadatos, estilos y script cliente. Rara vez necesitas un export Layout.
Exporta Layout desde root.tsx para configurar ArdoRootLayout:
import type { ReactNode } from "ardo/react"
import { ArdoRootLayout } from "ardo/ui"
export function Layout({ children }: { children: ReactNode }) {
return <ArdoRootLayout colorScheme="light">{children}</ArdoRootLayout>
}
Un shell completamente propio renderiza ArdoHead en <head> y ArdoScripts al final de <body>. Ambos proceden de ardo/runtime. ArdoHead renderiza los descriptores meta, estilos y precargas; ArdoScripts carga la entrada cliente de hidratación. El shell debe renderizar children:
import type { ReactNode } from "ardo/react"
import { ArdoHead, ArdoScripts } from "ardo/runtime"
export function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<ArdoHead />
</head>
<body>
{children}
<ArdoScripts />
</body>
</html>
)
}
Un shell propio no incluye la inicialización del tema ni los favicons de ArdoRootLayout. Prefiere envolver ArdoRootLayout salvo que el sitio necesite controlar todo el documento.
Páginas de error
root.tsx puede exportar ErrorBoundary. Una página ausente aparece dentro de la raíz con navegación; un error de render reemplaza la raíz para seguir visible. Sin export, Ardo usa ArdoErrorBoundary de ardo/ui.
import { ArdoErrorBoundary } from "ardo/ui"
export const ErrorBoundary = ArdoErrorBoundary
Esquema de color de RootLayout
Con colorScheme="auto", ArdoRootLayout prioriza ardo-theme guardado y después prefers-color-scheme. Fija un esquema para desactivar la elección del usuario:
export function Layout({ children }: { children: ReactNode }) {
return <ArdoRootLayout colorScheme="light">{children}</ArdoRootLayout>
}
| Esquema de color | Comportamiento |
|---|---|
auto | Preferencia guardada o del sistema. Predeterminado. |
light | Siempre claro; borra la elección guardada. |
dark | Siempre oscuro; borra la elección guardada. |
system | Siempre prefers-color-scheme; borra la elección guardada. |
Desplazamiento del documento con interfaz propia
scrollMode="document" sirve para cabeceras y pies externos o desplazamiento normal. El shell de viewport sigue siendo el predeterminado. En modo documento, navegación y panel se fijan bajo la altura de cabecera configurada; el pie externo sigue accesible. También funciona con className propia, que debe aportar las reglas de visualización y anchura.
Coloca cabecera adherente y pie junto a ArdoRoot. Desactiva los equivalentes de Ardo si son externos:
export default function Root() {
return (
<>
<SiteHeader />
<ArdoRoot scrollMode="document" header={false} footer={false} />
<SiteFooter />
</>
)
}
--ardo-layout-headerHeight ajusta posiciones y espacio de anclas. Defínela en ArdoRootLayout mediante Layout para compartirla con la cabecera y adáptala al breakpoint móvil:
export function Layout({ children }: { children: ReactNode }) {
return <ArdoRootLayout className="docs-site">{children}</ArdoRootLayout>
}
.docs-site {
--ardo-layout-headerHeight: 4rem;
}
@media (max-width: 640px) {
.docs-site {
--ardo-layout-headerHeight: 6rem;
}
}
.site-header {
position: sticky;
top: 0;
height: var(--ardo-layout-headerHeight);
}
Una cabecera adhesiva sigue en el flujo y no necesita espacio superior adicional. Una cabecera fija queda fuera del flujo; reserva su altura una sola vez con padding-top: var(--ardo-layout-headerHeight) en el wrapper. Para una ruta MDX con interfaz propia, exporta:
export const handle = { chrome: false }
La cabecera y pie externos siguen la misma regla; Ardo conserva navegación y panel. Las rutas sin su interfaz deben proporcionar un enlace de salto.