Data Fetching y APIs en Astro
Astro es un framework estático por naturaleza, pero te permite traer datos en tiempo de construcción o en tiempo real, lo que lo hace ideal tanto para webs informativas como para aplicaciones dinámicas.
1. ¿Qué significa data fetching? #
Data fetching = “obtener datos”.
Puedes traer datos de:
- Archivos JSON o locales.
- APIs externas (por ejemplo, el clima, usuarios, etc.).
- Bases de datos (con adaptadores o funciones server-side).
💡 En Astro, normalmente se obtienen en el servidor (dentro de los ---) antes de renderizar la página.
2. Obtener datos desde un archivo local (JSON) #
Supón que tienes un archivo:
src/data/cursos.json
1[ 2 { "id": 1, "nombre": "HTML y CSS", "nivel": "Básico" }, 3 { "id": 2, "nombre": "JavaScript", "nivel": "Intermedio" }, 4 { "id": 3, "nombre": "Astro", "nivel": "Avanzado" } 5]
Puedes leerlo en una página Astro así:
1--- 2import cursos from '../data/cursos.json'; 3--- 4 5<h1>Cursos disponibles</h1> 6<ul> 7 {cursos.map(curso => ( 8 <li> 9 {curso.nombre} — <em>{curso.nivel}</em> 10 </li> 11 ))} 12</ul>
✅ Se renderiza todo en el servidor. ✅ El usuario solo recibe HTML (sin necesidad de JavaScript extra).
3. Obtener datos desde una API externa #
Puedes usar fetch() directamente en la parte superior del archivo .astro:
1--- 2const respuesta = await fetch("https://jsonplaceholder.typicode.com/users"); 3const usuarios = await respuesta.json(); 4--- 5 6<h1>Lista de usuarios</h1> 7<ul> 8 {usuarios.map(u => <li>{u.name} — {u.email}</li>)} 9</ul>
💡 Esto se ejecuta una vez durante la compilación (en astro build),
por lo que los datos se guardan en el HTML final (rendimiento máximo 🚀).
4. Obtener datos en tiempo real (server-side rendering) #
Astro también puede obtener datos cada vez que alguien visita la página, en lugar de precompilarla. Esto se llama SSR (Server-Side Rendering).
Paso 1. Activar SSR #
Edita astro.config.mjs:
1import { defineConfig } from "astro/config"; 2 3export default defineConfig({ 4 output: "server", 5});
Paso 2. Crear una página SSR #
1--- 2const res = await fetch("https://api.coindesk.com/v1/bpi/currentprice.json"); 3const data = await res.json(); 4const precio = data.bpi.EUR.rate; 5--- 6 7<h1>Precio actual del Bitcoin</h1> 8<p>1 BTC = {precio} €</p>
💡 Ahora, cada vez que alguien entra, Astro consulta la API en directo.
✅ Ideal para datos cambiantes (clima, precios, noticias…). ❌ Menos rápido que una página estática (ya que consulta el servidor cada vez).
5. Crear páginas dinámicas con datos externos #
Imagina que quieres crear una página por cada usuario que viene de una API.
Paso 1. Crear una página dinámica #
src/pages/users/[id].astro
1--- 2// 1. En modo estático (SSG por defecto), genera las rutas en el build: 3export async function getStaticPaths() { 4 const res = await fetch("https://jsonplaceholder.typicode.com/users"); 5 const users = await res.json(); 6 return users.map((user) => ({ 7 params: { id: user.id.toString() }, 8 props: { user }, 9 })); 10} 11 12// 2. Recibe los datos precompilados de cada usuario 13const { user } = Astro.props; 14--- 15 16<h1>{user.name}</h1> 17<p>Email: {user.email}</p> 18<p>Ciudad: {user.address.city}</p>
💡 (Si tuvieras activado SSR con output: 'server' o export const prerender = false, no necesitas getStaticPaths y puedes leer const { id } = Astro.params directamente en cada petición).
Paso 2. Crear enlaces a cada usuario #
src/pages/users/index.astro
1--- 2const res = await fetch("https://jsonplaceholder.typicode.com/users"); 3const users = await res.json(); 4--- 5 6<h1>Usuarios</h1> 7<ul> 8 {users.map(u => <li><a href={`/users/${u.id}`}>{u.name}</a></li>)} 9</ul>
🟢 Cada usuario tendrá su propia página dinámica con datos reales.
6. Usar endpoints personalizados (rutas API) #
Astro también puede actuar como un mini backend. Puedes crear rutas API que devuelvan datos en formato JSON.
Ejemplo:
src/pages/api/hora.js
1export async function GET() { 2 return new Response( 3 JSON.stringify({ hora: new Date().toLocaleTimeString() }), 4 { headers: { "Content-Type": "application/json" } } 5 ); 6}
Y puedes acceder desde el navegador:
👉 /api/hora
Resultado:
1{ "hora": "15:42:09" }
💡 Muy útil para:
- Probar funciones backend.
- Crear APIs personalizadas.
- Servir datos a otros sitios o apps.
7. Ejemplo completo: Mostrar clima real #
1--- 2const ciudad = "Madrid"; 3const res = await fetch(`https://wttr.in/${ciudad}?format=j1`); 4const data = await res.json(); 5const temp = data.current_condition[0].temp_C; 6const desc = data.current_condition[0].weatherDesc[0].value; 7--- 8 9<h1>El tiempo en {ciudad}</h1> 10<p>Temperatura: {temp} °C</p> 11<p>Condición: {desc}</p>
🟢 Se obtiene la temperatura en tiempo real desde una API pública. 🟣 Puedes cambiar “Madrid” por cualquier ciudad.
8. Cuándo usar cada tipo de data fetching #
| Tipo de dato | Cuándo usarlo | Ejemplo |
|---|---|---|
| Local (JSON, Markdown) | Datos estáticos que no cambian | Blog, productos fijos |
| API externa (estático) | Datos externos pero poco cambiantes | Listado de usuarios |
| SSR (tiempo real) | Datos que cambian constantemente | Clima, precios, cotizaciones |
| Rutas API | Cuando quieres crear tu propio backend | /api/datos |
Resumen del tema
Conceptos clave #
- Fetch en tiempo de compilación (SSG por defecto): llamadas asíncronas con
await fetch()en el frontmatter que se ejecutan duranteastro build, inyectando los datos directamente en el HTML final. - Server-Side Rendering (SSR): activación mediante
output: 'server'enastro.config.mjspara consultar APIs y bases de datos en tiempo real en cada petición. - Carga de datos locales: importación directa de archivos JSON (
import datos from '../data/datos.json') procesados en el servidor sin transferir sobrecarga al cliente. - Endpoints y Rutas API (
src/pages/api/): creación de funciones serverless exportando métodos HTTP (GET,POST,PUT,DELETE) que devuelven objetos estándarResponse(JSON.stringify(...)). - Rutas parametrizadas dinámicas: consumo de parámetros mediante
Astro.paramspara filtrar y renderizar vistas de detalle basadas en IDs o slugs.
Qué debes recordar #
En Astro, las llamadas a fetch() en el frontmatter se ejecutan en el servidor/build sin enviar JavaScript al cliente; usa endpoints API (GET/POST) para construir servicios backend ligeros.