Astro.params y Astro.request
Accede a parámetros de URL y datos de peticiones HTTP en tus páginas Astro
Objetos globales de Astro
Astro proporciona objetos globales especiales que te permiten acceder a información sobre la petición HTTP actual. Los dos más importantes son:
Astro.params
Accede a los parámetros dinámicos de la URL
Astro.request
Accede a información completa de la petición HTTP
1. Astro.params
¿Qué es Astro.params?
Astro.params es un objeto que contiene los valores de los parámetros dinámicos de tu ruta.
Ejemplo: Si tienes una ruta /blog/[slug].astro y visitas /blog/mi-post
Entonces: Astro.params.slug === "mi-post"
1---2// src/pages/blog/[slug].astro3 4export function getStaticPaths() {5 return [6 { params: { slug: 'aprendiendo-astro' } },7 { params: { slug: 'javascript-moderno' } },8 { params: { slug: 'css-avanzado' } }9 ];10}11 12// Obtener el parámetro de la URL13const { slug } = Astro.params;14---15 16<html>17 <body>18 <h1>Post: {slug}</h1>19 <p>Estás leyendo el artículo: {slug}</p>20 </body>21</html>Múltiples parámetros
Puedes tener varios parámetros en una misma ruta:
1---2// src/pages/[categoria]/[producto].astro3 4export function getStaticPaths() {5 return [6 { params: { categoria: 'tecnologia', producto: 'laptop' } },7 { params: { categoria: 'tecnologia', producto: 'mouse' } },8 { params: { categoria: 'libros', producto: 'novela' } }9 ];10}11 12const { categoria, producto } = Astro.params;13---14 15<html>16 <body>17 <h1>Categoría: {categoria}</h1>18 <h2>Producto: {producto}</h2>19 <p>Ruta: /{'{}'}categoria{'{}'}}/{'{}'}producto{'{}'}}</p>20 </body>21</html>22 23<!--24 Rutas generadas:25 /tecnologia/laptop26 /tecnologia/mouse27 /libros/novela28-->Rutas catch-all
Con rutas catch-all [...slug], el parámetro es una cadena con la ruta completa:
1---2// src/pages/docs/[...slug].astro3 4export function getStaticPaths() {5 return [6 { params: { slug: 'introduccion' } },7 { params: { slug: 'guia/instalacion' } },8 { params: { slug: 'api/fetch/ejemplos' } }9 ];10}11 12const { slug } = Astro.params;13---14 15<html>16 <body>17 <h1>Documentación</h1>18 <p>Ruta: {slug}</p>19 <!--20 Para /docs/guia/instalacion21 slug = "guia/instalacion"22 -->23 </body>24</html> Nota: Con catch-all, el valor es un string que incluye todas las barras. Por ejemplo: "guia/instalacion"
2. Astro.request
¿Qué es Astro.request?
Astro.request es un objeto estándar de tipo Request que contiene información sobre la petición HTTP actual.
Es una instancia de: Request (API Web estándar)
Propiedades más usadas
Astro.request.url
La URL completa de la petición
1---2const url = new URL(Astro.request.url);3console.log(url.href); // "http://localhost:4321/blog/post-1"4console.log(url.pathname); // "/blog/post-1"5console.log(url.host); // "localhost:4321"6---Astro.request.headers
Los headers HTTP de la petición
1---2const userAgent = Astro.request.headers.get('user-agent');3const contentType = Astro.request.headers.get('content-type');4const referer = Astro.request.headers.get('referer');5 6console.log('User Agent:', userAgent);7---Astro.request.method
El método HTTP usado (GET, POST, etc.)
1---2const method = Astro.request.method;3console.log(method); // "GET", "POST", "PUT", etc.4 5if (method === 'POST') {6 // Manejar petición POST7 const formData = await Astro.request.formData();8}9---Acceder a Query Parameters
Los parámetros de consulta (query params) se obtienen parseando la URL:
1---2// Para URL: /productos?categoria=tecnologia&precio=1003 4const url = new URL(Astro.request.url);5const params = url.searchParams;6 7const categoria = params.get('categoria'); // "tecnologia"8const precio = params.get('precio'); // "100"9 10// O todos a la vez11const allParams = Object.fromEntries(params);12// { categoria: "tecnologia", precio: "100" }13---14 15<html>16 <body>17 <h1>Productos</h1>18 {categoria && <p>Categoría: {categoria}</p>}19 {'{'}precio && <p>Precio máximo: {precio{'}'}</p>{'}'}20 </body>21</html>Tip: Los query params son útiles para filtros, paginación, búsquedas, etc.
3. Diferencias clave
Astro.params
Solo parámetros de ruta dinámica
Valores de [id], [slug], etc.
Definidos en getStaticPaths()
Siempre es un objeto simple
Astro.params.id
Astro.params.slug
Astro.request
Información completa de la petición HTTP
URL, headers, método, body, etc.
Query params via searchParams
Objeto Request estándar
Astro.request.url
Astro.request.headers
4. Ejemplos prácticos y visuales
📱 Ejemplo 1: Tienda online - Página de producto
🌐 URLs de ejemplo:
1---2// src/pages/tienda/[id].astro3 4export async function getStaticPaths() {5 // Llamada a la API REST de productos6 const response = await fetch('https://api.tutienda.com/productos');7 const productos = await response.json();8 9 // Ejemplo de respuesta de la API:10 // [11 // { id: 'laptop-gaming', nombre: 'Laptop Gaming Pro', precio: 1299, stock: 5 },12 // { id: 'mouse-rgb', nombre: 'Mouse RGB Ultra', precio: 49, stock: 0 },13 // { id: 'teclado-mecanico', nombre: 'Teclado Mecánico', precio: 89, stock: 15 }14 // ]15 16 return productos.map(producto => ({17 params: { id: producto.id },18 props: { producto }19 }));20}21 22const { id } = Astro.params;23const { producto } = Astro.props;24 25// También podríamos hacer la llamada aquí si usamos SSR:26// const response = await fetch(`https://api.tutienda.com/productos/${id}`);27// const producto = await response.json();28---29 30<html>31 <head>32 <title>{'producto.nombre'} - Mi Tienda</title>33 </head>34 <body>35 <div class="producto-card">36 <h1>{'producto.nombre'}</h1>37 <p class="precio">producto.precio</p>38 39 {producto.stock > 0 ? (40 <div class="disponible">41 <p>✅ En stock: {'producto.stock'} unidades</p>42 <button>Agregar al carrito</button>43 </div>44 ) : (45 <div class="agotado">46 <p>❌ Producto agotado</p>47 <button disabled>No disponible</button>48 </div>49 )}50 51 <p class="id-producto">ID: {'id'}</p>52 </div>53 </body>54</html> 💡 Uso real: Cada producto tiene su propia URL amigable. El parámetro id se usa para mostrar el producto correcto.
📺 Lo que se muestra al usuario:
URL visitada:
/tienda/laptop-gaming
Laptop Gaming Pro
$1299
✅ En stock: 5 unidades
ID: laptop-gaming
URL visitada:
/tienda/mouse-rgb
Mouse RGB Ultra
$49
❌ Producto agotado
ID: mouse-rgb
🔍 Cómo funciona: Astro.params.id extrae "laptop-gaming" de la URL y busca ese producto en la base de datos.
🔍 Ejemplo 2: Sistema de filtros para e-commerce
🌐 URL con filtros:
1---2// src/pages/productos.astro3 4// Obtener parámetros de la URL5const url = new URL(Astro.request.url);6const params = url.searchParams;7 8const categoria = params.get('categoria') || 'todas';9const precioMax = parseInt(params.get('precio_max') || '999999');10const orden = params.get('orden') || 'nombre';11 12// Construir query string para la API13const queryParams = new URLSearchParams({14 categoria: categoria !== 'todas' ? categoria : '',15 precio_max: precioMax.toString(),16 orden: orden17}).toString();18 19// Llamada a la API REST con filtros20const response = await fetch(`https://api.tutienda.com/productos?${queryParams}`);21const productos = await response.json();22 23// La API devuelve los productos ya filtrados y ordenados:24// {25// "total": 2,26// "filtros": { "categoria": "tecnologia", "precio_max": 500 },27// "productos": [28// { "nombre": "Mouse", "categoria": "tecnologia", "precio": 25 },29// { "nombre": "Auriculares", "categoria": "tecnologia", "precio": 150 }30// ]31// }32---33 34<html>35 <head>36 <title>Productos - Filtros aplicados</title>37 </head>38 <body>39 <h1>Catálogo de Productos</h1>40 41 <!-- Formulario de filtros -->42 <form method="get" class="filtros">43 <div>44 <label>Categoría:</label>45 <select name="categoria" value={'categoria'}>46 <option value="todas">Todas</option>47 <option value="tecnologia">Tecnología</option>48 <option value="libros">Libros</option>49 </select>50 </div>51 52 <div>53 <label>Precio máximo:</label>54 <input type="number" name="precio_max" value={'precioMax'} />55 </div>56 57 <div>58 <label>Ordenar por:</label>59 <select name="orden" value={'orden'}>60 <option value="nombre">Nombre</option>61 <option value="precio">Precio</option>62 </select>63 </div>64 65 <button type="submit">Aplicar filtros</button>66 </form>67 68 <!-- Mostrar filtros activos -->69 <div class="filtros-activos">70 <p>📊 Filtros activos:</p>71 <ul>72 <li>Categoría: <strong>{'categoria'}</strong></li>73 <li>Precio máximo: <strong>precioMax</strong></li>74 <li>Ordenar: <strong>{'orden'}</strong></li>75 </ul>76 </div>77 78 <!-- Resultados -->79 <div class="resultados">80 <p>Encontrados: {'productos.length'} productos</p>81 82 <div class="grid">83 {productos.map(producto => (84 <div class="card">85 <h3>{'producto.nombre'}</h3>86 <p class="categoria">{'producto.categoria'}</p>87 <p class="precio">producto.precio</p>88 </div>89 ))}90 </div>91 </div>92 </body>93</html>📺 Lo que se muestra al usuario:
URL con filtros:
/productos?categoria=tecnologia&precio_max=500&orden=precio
📊 Filtros activos:
✅ Encontrados: 2 productos
Mouse
tecnologia
$25
Auriculares
tecnologia
$150
🔍 Cómo funciona: searchParams.get() extrae cada parámetro de la URL y filtra/ordena los productos según esos valores.
📝 Ejemplo 3: Blog con navegación por categorías
🌐 Rutas del blog:
→ slug = "async-await"
1---2// src/pages/blog/[categoria]/[slug].astro3 4export async function getStaticPaths() {5 // Llamada a la API REST del blog6 const response = await fetch('https://api.miblog.com/posts');7 const posts = await response.json();8 9 // La API devuelve todos los posts:10 // [11 // { categoria: 'javascript', slug: 'async-await', titulo: '...', ... },12 // { categoria: 'javascript', slug: 'arrays-modernos', titulo: '...', ... },13 // { categoria: 'css', slug: 'flexbox', titulo: '...', ... }14 // ]15 16 return posts.map(post => ({17 params: {18 categoria: post.categoria,19 slug: post.slug20 },21 props: { post }22 }));23}24 25const { categoria, slug } = Astro.params;26const { post } = Astro.props;27 28// En SSR, haríamos:29// const response = await fetch(`https://api.miblog.com/posts/${categoria}/${slug}`);30// const post = await response.json();31---32 33<html>34 <head>35 <title>{'post.titulo'} | Mi Blog</title>36 </head>37 <body>38 <!-- Breadcrumb navegación -->39 <nav class="breadcrumb">40 <a href="/blog">Blog</a> →41 <a href={`/blog/{'categoria'}`}>{'categoria'}</a> →42 <span>{'post.titulo'}</span>43 </nav>44 45 <!-- Artículo principal -->46 <article>47 <header>48 <span class="categoria-badge">{'categoria'}</span>49 <h1>{'post.titulo'}</h1>50 <time>{'post.fecha'}</time>51 </header>52 53 <div class="contenido">54 {'post.contenido'}55 </div>56 </article>57 58 <!-- Info sobre params -->59 <div class="debug-info">60 <p>📍 Parámetros de URL:</p>61 <code>categoria: {'categoria'}</code>62 <code>slug: {'slug'}</code>63 </div>64 </body>65</html>📺 Lo que se muestra al usuario:
URL visitada:
/blog/javascript/async-await
Guía de Async/Await
📅 2024-01-15
📍 Parámetros extraídos:
🔍 Cómo funciona: Se extraen MÚLTIPLES parámetros (categoria y slug) de la URL para mostrar el post correcto y su categoría.
👤 Ejemplo 4: Panel de usuario con tabs
🌐 Dashboard con tab activo:
1---2// src/pages/dashboard.astro3 4const url = new URL(Astro.request.url);5const tabActivo = url.searchParams.get('tab') || 'resumen';6const periodo = url.searchParams.get('periodo') || 'semana';7 8// Llamada a la API del dashboard con filtros9const apiUrl = `https://api.dashboard.com/${tabActivo}?periodo=${periodo}`;10const response = await fetch(apiUrl);11const datos = await response.json();12 13// Ejemplos de respuestas según el tab:14//15// GET /resumen?periodo=mes:16// { "ventas": 1250, "pedidos": 45, "usuarios": 120 }17//18// GET /pedidos?periodo=mes:19// [20// { "id": 1, "cliente": "Juan", "total": 299, "estado": "enviado" },21// { "id": 2, "cliente": "María", "total": 150, "estado": "pendiente" }22// ]23---24 25<html>26 <head>27 <title>Dashboard - {'tabActivo'}</title>28 </head>29 <body>30 <div class="dashboard">31 <h1>Panel de Control</h1>32 33 <!-- Navegación por tabs -->34 <nav class="tabs">35 <a36 href="?tab=resumen"37 class={tabActivo === 'resumen' ? 'activo' : ''}38 >39 📊 Resumen40 </a>41 <a42 href="?tab=pedidos"43 class={tabActivo === 'pedidos' ? 'activo' : ''}44 >45 📦 Pedidos46 </a>47 <a48 href="?tab=usuarios"49 class={tabActivo === 'usuarios' ? 'activo' : ''}50 >51 👥 Usuarios52 </a>53 </nav>54 55 <!-- Contenido según tab -->56 {tabActivo === 'resumen' && (57 <div class="stats">58 <div class="stat-card">59 <h3>Ventas</h3>60 <p>datos.resumen.ventas</p>61 </div>62 <div class="stat-card">63 <h3>Pedidos</h3>64 <p>{'datos.resumen.pedidos'}</p>65 </div>66 </div>67 )}68 69 {tabActivo === 'pedidos' && (70 <table>71 <thead>72 <tr>73 <th>ID</th>74 <th>Cliente</th>75 <th>Total</th>76 </tr>77 </thead>78 <tbody>79 {datos.pedidos.map(pedido => (80 <tr>81 <td>#{'pedido.id'}</td>82 <td>{'pedido.cliente'}</td>83 <td>pedido.total</td>84 </tr>85 ))}86 </tbody>87 </table>88 )}89 </div>90 </body>91</html>📺 Lo que se muestra al usuario:
URL con query params:
/dashboard?tab=pedidos&periodo=mes
Panel de Control
| ID | Cliente | Total |
|---|---|---|
| #1 | Juan | $299 |
| #2 | María | $150 |
📍 Query params extraídos:
🔍 Cómo funciona: Los query params mantienen el estado de la UI (qué tab está activo) en la URL, permitiendo compartir enlaces directos.
5. Resumen
Astro.params: Accede a parámetros de ruta dinámica ([id], [slug])
Astro.request: Objeto Request con información completa de la petición HTTP
Query params: Usa new URL(Astro.request.url).searchParams
Headers: Accede con Astro.request.headers.get('nombre')
Método HTTP: Verifica con Astro.request.method
Próximos pasos
En la siguiente lección aprenderás sobre las diferencias entre SSG y SSR, y cuándo usar cada estrategia de renderizado.