Saltar al contenido

La API de fuentes de Astro

El origen de la API de fuentes como experimental.fonts, su estabilización en Astro 7 y la declaración de familias en el arreglo fonts: provider, name y cssVariable como contrato, con proveedores locales y remotos que Astro descarga, optimiza y autoaloja por ti.

De la fontanería manual a una declaración

El método clásico para usar una fuente web mezclaba tres piezas dispersas: un enlace de preconexión al origen del CDN, una hoja de estilos remota que definía las reglas @font-face, y la esperanza de que todo llegara a tiempo. Escrito a mano, se veía así.

HTML
<link rel="preconnect" href="https://fonts.googleapis.com" /><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /><link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet" />

Cada línea esconde un coste: un viaje a otro dominio, una dependencia de tiempo de ejecución, y ninguna garantía sobre qué pesos o subconjuntos acaban descargándose. Y aún faltaba lo peor. Mientras la fuente viajaba por la red, el navegador tenía que decidir qué mostrar: o bien ocultaba el texto hasta que llegara, dejando un hueco en blanco, o bien lo pintaba con una fuente de respaldo y luego lo reemplazaba de golpe, desplazando la maquetación. Esas dos patologías, el texto invisible y el salto de contenido, eran el precio tácito de cada fuente web, y corregirlas a mano exigía un conocimiento fino que casi nadie tenía tiempo de aplicar.

La API de fuentes de Astro invierte el planteamiento. En lugar de enlazar recursos ajenos en cada página, declaras las familias una vez en la configuración y dejas que el framework resuelva el resto en el build. La fuente deja de ser un enlace externo y pasa a ser un activo de tu proyecto, tan versionado y controlado como una imagen. Las patologías clásicas dejan de ser tu problema porque el framework las ataca por defecto, un tema que desmenuzaremos en las lecciones sobre el componente y el rendimiento.

El arreglo fonts: anatomía de una familia

La declaración vive en astro.config.mjs, en un arreglo fonts donde cada objeto describe una familia. Tres claves son obligatorias y bastan para empezar: el provider, que dice de dónde sale la fuente; el name, el nombre de la familia tal como lo conoce ese proveedor; y el cssVariable, el identificador con el que la consumirás desde el CSS.

ASTRO
---// astro.config.mjsimport { defineConfig, fontProviders } from 'astro/config';export default defineConfig({  fonts: [    {      provider: fontProviders.google(),      name: 'Inter',      cssVariable: '--font-inter',    },  ],});

El cssVariable es la pieza conceptualmente más importante: es el contrato entre la configuración y tus estilos. No escribes el nombre de la fuente en el CSS ni te preocupas por su pila de fallbacks; te refieres a ella por esa variable, y Astro garantiza que apunte a la familia correcta, con sus respaldos, allí donde la uses. La configuración y el diseño quedan acoplados solo por ese nombre, no por los detalles de descarga.

Proveedores locales y remotos

El provider decide el origen. Un proveedor remoto como fontProviders.google() o fontProviders.fontsource() resuelve la familia contra un catálogo en la red y descarga sus archivos durante el build. Un proveedor local, fontProviders.local(), no busca nada fuera: toma archivos que ya tienes en el disco y los declara como variantes, cada una un @font-face con su src.

ASTRO
---// astro.config.mjsimport { defineConfig, fontProviders } from 'astro/config';export default defineConfig({  fonts: [    {      provider: fontProviders.local(),      name: 'Geist',      cssVariable: '--font-geist',      options: {        variants: [          { weight: 400, style: 'normal', src: ['./src/assets/fonts/Geist-400.woff2'] },          { weight: 700, style: 'normal', src: ['./src/assets/fonts/Geist-700.woff2'] },        ],      },    },  ],});

La diferencia práctica es de procedencia, no de trato: una vez resuelta, Astro autoaloja ambas por igual. Da igual que la fuente viniera de Google o de tu carpeta src/assets; en la salida del build, todas se sirven desde tu propio origen con las mismas optimizaciones. El proveedor es solo la puerta por la que entra la fuente, no cómo se sirve después.

Sobre esas tres claves obligatorias se apilan otras opcionales que afinan qué se descarga y cómo se comporta: weights para elegir grosores, styles para normal o cursiva, subsets para acotar los rangos de caracteres, fallbacks para la pila de respaldo y display para la estrategia de intercambio. No las necesitas para empezar, y sus valores por defecto son sensatos, pero son las palancas con las que más adelante recortarás el peso y borrarás los saltos de maquetación.

ASTRO
---// astro.config.mjs: la misma familia, ya refinadaexport default defineConfig({  fonts: [    {      provider: fontProviders.google(),      name: 'Inter',      cssVariable: '--font-inter',      weights: [400, 600, 700],      styles: ['normal'],      subsets: ['latin', 'latin-ext'],    },  ],});

Por ahora basta con retener la forma esencial: una familia es un proveedor, un nombre y una variable, y todo lo demás es refinamiento que puedes añadir el día que lo necesites, sin reescribir nada de lo anterior.