Websites con Quarto

quarto
reproducibilidad
De un .qmd suelto a un sitio web completo. Estructura de proyecto, navbar, sidebar, listings para blogs y catálogos, temas, y los detalles que separan un sitio amateur de uno editorial.

Crear un proyecto website

Desde la línea de comandos:

quarto create project website mi-sitio
cd mi-sitio

Estructura inicial:

mi-sitio/
├── _quarto.yml          ← configuración del proyecto
├── index.qmd            ← portada
├── about.qmd            ← página "Sobre"
└── styles.css           ← estilos personalizados

Para renderizar y servir con auto-reload:

quarto preview

Abre localhost:4848 (puerto típico) con el sitio. Editas un .qmd, se actualiza solo. Es el modo de trabajo.

_quarto.yml: la configuración

project:
  type: website

website:
  title: "Mi sitio"
  description: "Análisis y notas sobre datos"
  site-url: https://misitio.com
  navbar:
    background: primary
    left:
      - href: index.qmd
        text: Inicio
      - href: blog/index.qmd
        text: Blog
      - href: about.qmd
        text: Sobre
    right:
      - icon: github
        href: https://github.com/usuario
        aria-label: GitHub

format:
  html:
    theme: cosmo
    css: styles.css
    toc: true

Tres bloques clave:

  • project: tipo de proyecto (website, book, default).
  • website: configuración del sitio (título, navbar, sidebar).
  • format: opciones de HTML que aplican a todas las páginas.

Listings: blog y catálogos

El listing de Quarto es lo que más distingue a un sitio Quarto profesional. Genera automáticamente una página con tarjetas de los .qmd de una carpeta.

En blog/index.qmd:

---
title: "Blog"
listing:
  contents: posts/
  type: default
  sort: "date desc"
  fields: [date, title, description, categories]
  page-size: 10
  feed: true
---

Y cada post en blog/posts/2026-05-15-titulo.qmd:

---
title: "Mi post"
description: "Resumen corto"
date: 2026-05-15
categories: [quarto, reproducibilidad]
---

Contenido del post...

El listing genera:

  • Una tarjeta por post con título, descripción, fecha, categorías.
  • Ordenación por fecha (más reciente primero).
  • Paginación si hay más de 10.
  • RSS feed automático (feed: true).

Tres type de listing:

  • default: lista vertical clásica.
  • grid: cuadrícula de tarjetas con imagen.
  • table: tabla.

Para blogs serios, default con imagen lateral. Para catálogos visuales (galería, recursos), grid.

Configuración avanzada del listing

listing:
  contents: posts/
  type: grid
  grid-columns: 3
  image-placeholder: default.svg
  fields: [image, date, title, description, categories]
  field-display-names:
    date: "Publicado"
  sort:
    - "date desc"
    - "title asc"
  filter-ui: true
  categories: true
  page-size: 12
  • grid-columns: número de columnas (responsive).
  • image-placeholder: fallback si el post no tiene image:.
  • field-display-names: etiquetas visibles distintas a las internas.
  • filter-ui: true: añade caja de búsqueda en el listing.
  • categories: true: pestañas para filtrar por categoría.

Lo veo idéntico al patrón de revistas digitales modernas.

Categorías y tags

Cada documento puede declarar categories: en el YAML:

categories: [quarto, reproducibilidad]

En el listing, Quarto genera pestañas o sidebar para filtrar por categoría, sin tener que escribir lógica. Lo gestiona todo.

Multi-listing

Una página puede tener varios listings (ej. “destacados” + “recientes”):

listing:
  - id: destacados
    contents: posts/destacados/
    type: grid
  - id: recientes
    contents: posts/
    sort: "date desc"
    max-items: 5

En el cuerpo:

## Destacados

::: {#destacados}
:::

## Recientes

::: {#recientes}
:::

Patrón ideal para landing pages.

Themes: built-in y SCSS

Built-in:

format:
  html:
    theme: cosmo

20+ themes integrados (cosmo, flatly, journal, litera, darkly, cyborg…). Cambias una línea, el sitio entero cambia.

Para algo personal:

format:
  html:
    theme:
      light: [cosmo, theme-light.scss]
      dark:  [darkly, theme-dark.scss]

theme-light.scss y theme-dark.scss son archivos SCSS con variables Bootstrap personalizadas:

// theme-light.scss

/*-- scss:defaults --*/
$primary: #5F8575;
$body-bg: #FAF9F6;
$body-color: #2A2A2A;
$font-family-sans-serif: 'Inter Tight', system-ui, sans-serif;
$headings-font-family: 'Newsreader', Georgia, serif;
$headings-font-weight: 500;

/*-- scss:rules --*/
.navbar-brand {
    letter-spacing: -0.5px;
}

Dos secciones: /*-- scss:defaults --*/ (variables) y /*-- scss:rules --*/ (CSS adicional). Es el sistema que usa Bootstrap 5 internamente.

Switcher light/dark

Con theme.light y theme.dark definidos, Quarto automáticamente añade un toggle en la navbar para cambiar entre modos. Detalle pequeño, gran percepción de calidad.

SEO básico

Lo mínimo razonable:

website:
  site-url: https://misitio.com
  description: "Descripción que aparece en buscadores"
  open-graph: true
  twitter-card: true

open-graph y twitter-card activan las tarjetas previas cuando alguien comparte un enlace en Slack, Twitter, LinkedIn. Importante para visibilidad social.

Cada página puede tener su propio description: y image:.

Estructura recomendada para proyectos medios

mi-sitio/
├── _quarto.yml
├── theme-light.scss
├── theme-dark.scss
├── index.qmd
├── about.qmd
├── blog/
│   ├── index.qmd          ← listing del blog
│   └── posts/
│       ├── 2026-05-15-post1.qmd
│       └── 2026-05-20-post2.qmd
├── tutoriales/
│   ├── index.qmd          ← listing de tutoriales
│   └── *.qmd
└── _site/                 ← output (gitignore)

Una carpeta por tipo de contenido, cada una con su index.qmd que listing su contenido. Estructura escalable.

Comprobar lo que se publica

Antes de publicar, render completo:

quarto render

Output a _site/. Inspecciónalo localmente abriendo _site/index.html. Lo que ves ahí es exactamente lo que se publicará.

Trampas habituales

  • Olvidar site-url. Sin él, los enlaces absolutos (Open Graph, RSS) usan localhost. Define el dominio real desde el principio.
  • Listings con paths absolutos. contents: /posts/ falla. Siempre relativo: contents: posts/.
  • Categorías con espacios o tildes que no se filtran bien. Usa minúsculas, ASCII, guiones. r-base mejor que “R Básico”.
  • Themes con SCSS rotos. Si tu SCSS tiene un error, Quarto cae con mensaje sutil. Empieza con cambios mínimos (solo $primary), añade complejidad gradual.
  • Imágenes a tamaño completo en listings, explosión visual. En grid, recomendado: imágenes 1200×630 o cuadradas (1:1).

En la siguiente entrega

Tienes un sitio multi-página. Lo siguiente: libros con Quarto Book, la estructura para contenido largo con capítulos numerados, índice, referencias cruzadas entre capítulos, exportación a PDF/EPUB. Lo siguiente.