Volver al inicio
Lección 5: Astro.params y Astro.request

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].astro
3
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 URL
13const { 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].astro
3
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/laptop
26 /tecnologia/mouse
27 /libros/novela
28-->

Rutas catch-all

Con rutas catch-all [...slug], el parámetro es una cadena con la ruta completa:

1---
2// src/pages/docs/[...slug].astro
3
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/instalacion
21 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 POST
7 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=100
3
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 vez
11const 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:

/tienda/laptop-gaming → Astro.params.id = "laptop-gaming"
/tienda/mouse-rgb → Astro.params.id = "mouse-rgb"
1---
2// src/pages/tienda/[id].astro
3
4export async function getStaticPaths() {
5 // Llamada a la API REST de productos
6 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:

/productos?categoria=tecnologia&precio_max=500&orden=precio
→ categoria = "tecnologia"
→ precio_max = "500"
→ orden = "precio"
1---
2// src/pages/productos.astro
3
4// Obtener parámetros de la URL
5const 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 API
13const queryParams = new URLSearchParams({
14 categoria: categoria !== 'todas' ? categoria : '',
15 precio_max: precioMax.toString(),
16 orden: orden
17}).toString();
18
19// Llamada a la API REST con filtros
20const 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:

Categoría: tecnologia Precio máx: $500 Ordenar: precio

✅ 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:

/blog/javascript/async-await
→ categoria = "javascript"
→ slug = "async-await"
1---
2// src/pages/blog/[categoria]/[slug].astro
3
4export async function getStaticPaths() {
5 // Llamada a la API REST del blog
6 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.slug
20 },
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

BlogjavascriptGuía de Async/Await
javascript

Guía de Async/Await

📅 2024-01-15

Las promesas y async/await...

📍 Parámetros extraídos:

categoria: "javascript"
slug: "async-await"

🔍 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:

/dashboard?tab=pedidos&periodo=mes
→ tab = "pedidos"
→ periodo = "mes"
1---
2// src/pages/dashboard.astro
3
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 filtros
9const 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 <a
36 href="?tab=resumen"
37 class={tabActivo === 'resumen' ? 'activo' : ''}
38 >
39 📊 Resumen
40 </a>
41 <a
42 href="?tab=pedidos"
43 class={tabActivo === 'pedidos' ? 'activo' : ''}
44 >
45 📦 Pedidos
46 </a>
47 <a
48 href="?tab=usuarios"
49 class={tabActivo === 'usuarios' ? 'activo' : ''}
50 >
51 👥 Usuarios
52 </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

📊 Resumen
📦 Pedidos ← ACTIVO
👥 Usuarios
ID Cliente Total
#1 Juan $299
#2 María $150

📍 Query params extraídos:

tab: "pedidos" → Muestra la tabla de pedidos
periodo: "mes" → Filtra por mes

🔍 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.