Astro 5.7

Por
Matt Kane
Florian Lefebvre
Emanuele Stoppa
Nate Moore

Astro 5.7 tiene una cesta llena de sorpresas, incluyendo Sessions estables y componentes SVG y una nueva Fonts API experimental.

🐣 Lleno de las alegrías de la primavera del hemisferio norte, Astro 5.7 está aquí con montones de sorpresas:

Para actualizar un proyecto existente, usa la herramienta CLI automatizada @astrojs/upgrade. Alternativamente, actualiza manualmente ejecutando el comando de actualización para tu gestor de paquetes:

# Recommended:
npx @astrojs/upgrade
# Manual:
npm install astro@latest
pnpm upgrade astro --latest
yarn upgrade astro --latest

Fonts API experimental

Casi todos los sitios web hoy en día usan fuentes personalizadas. Sin embargo, puede ser sorprendentemente complicado hacerlas bien: ¿Por qué obtengo un Flash of Unstyled Text? ¿Debería añadir un preload link? ¿Qué hay de los preconnect links? ¿Self-host o confío en un proveedor de terceros?

Las fuentes pueden tener implicaciones significativas de rendimiento en tu sitio, afectando la experiencia de navegación de tus visitantes y métricas importantes de Core Web Vitals (CWV). Afortunadamente, las APIs web han mejorado mucho recientemente y gracias a iniciativas increíbles de la comunidad open source (ej. unifont y capsize), ¡hemos podido empezar a trabajar en una gran forma de usar fuentes en Astro!

Esta característica experimental te permite usar fuentes tanto de tu file system como de varios proveedores soportados integrados (ej. Google, Fontsource, Bunny) a través de una API unificada. Mantén tu sitio con buen rendimiento gracias a defaults sensatos y optimizaciones automáticas incluyendo generación de fallback fonts.

Para habilitar esta característica, configura un objeto experimental.fonts con una o más fuentes:

astro.config.mjs
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
experimental: {
fonts: [{
provider: fontProviders.google(),
name: "Roboto",
cssVariable: "--font-roboto"
}]
}
});

Luego, añade un componente <Font /> y estilos a nivel de sitio en tu <head>:

src/components/Head.astro
---
import { Font } from 'astro:assets'
---
<Font cssVariable='--font-roboto' preload />
<style>
body {
font-family: var(--font-roboto);
}
</style>

¡Hay mucho más por descubrir! Dirígete a la documentación experimental de Fonts para la API completa, cómo empezar, e incluso cómo construir tu propio AstroFontProvider personalizado si aún no soportamos tu servicio de fuentes preferido.

También apreciaríamos tu feedback. Participa en el desarrollo continuo de esta característica en el Fonts RFC y ayuda a dar forma a su futuro.

Sessions API

¡La Astro Sessions API ahora es estable y lista para producción!

Las sessions te permiten almacenar de forma segura datos vinculados a un usuario específico mientras navega entre las páginas de tu sitio. A diferencia de las cookies, las sessions se almacenan en el servidor, así que puedes almacenar mayores cantidades de datos sin preocuparte por límites de tamaño o problemas de seguridad. Son útiles para almacenar cosas como datos de usuario, carritos de compra, y estado de formularios, y funcionan sin ningún JavaScript del lado del cliente:

src/components/CartButton.astro
---
const cart = await Astro.session.get('cart');
export const prerender = false;
---
<a href="/checkout">🛒 {cart?.length ?? 0} items</a>

Se pueden usar en componentes de Astro, páginas, API endpoints, actions, y middleware. La API es la misma para todos ellos:

src/actions/addToCart.ts
import { defineAction } from "astro:actions";
import { z } from "astro:schema";
export const server = {
addToCart: defineAction({
input: z.object({
product: z.string(),
}),
async handler({ product }, { session }) {
const cart = await session.get('cart');
session.set('cart', [...cart, product]);
},
}),
};

Type-safety

Por supuesto, como esto es Astro, tus sessions también pueden ser type-safe. Define una interfaz y obtendrás type-checking y auto-completion para todos tus datos de session:

src/env.d.ts
declare namespace App {
interface SessionData {
user: {
id: string;
name: string;
};
cart: string[];
}
}

El session ID se rastrea automáticamente usando una cookie, pero también puedes usar el método session.load() para acceder a sessions sin cookies. Esto es útil para cosas como APIs, donde podrías querer usar un header personalizado o params para rastrear el session ID:

src/pages/api/cart.ts
export async function POST({ session, request }: APIContext) {
const sessionId = request.headers.get('x-session-id');
// If there is an existing session ID, load it. Otherwise, one will be created
if (sessionId) {
await session.load(sessionId);
}
const cart = await session.get('cart');
const data = await request.json<{ item: string }>();
if (!data?.item) {
return new Response('Item is required', { status: 400 });
}
session.set('cart', [...cart, data.item]);
// Return the cart and session ID
return Response.json({ cart, sessionId: session.sessionId });
}

Storage drivers

Las sessions de Astro usan storage drivers para persistir los datos, y estos son zero-config o requieren configuración mínima para todos los adaptadores oficiales de Astro. Alternativamente, puedes usar cualquier driver de unstorage, que soporta decenas de backends de almacenamiento como Redis y MongoDB.

  • Node: driver de filesystem zero-config
  • Netlify: driver de Netlify Blobs zero-config
  • Cloudflare: driver de Workers KV minimal-config
  • Vercel: driver de Redis/Upstash minimal-config

En cualquiera de estas plataformas, puedes cambiar fácilmente el driver por uno diferente si no quieres usar el por defecto.

astro.config.mjs
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';
export default defineConfig({
// ...
adapter: netlify(),
session: {
driver: 'redis',
options: {
url: process.env.REDIS_URL,
},
},
});

Actualizando desde sessions experimentales

Si estabas usando la sessions API experimental, debes eliminar el flag experimental de tu archivo astro.config.mjs:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
// ...
experimental: {
session: false,
},
});

Consulta la guía de sessions para saber más sobre cómo usarlas en tu proyecto de Astro.

Componentes SVG

¡Astro ahora soporta archivos SVG locales como componentes! Inliner SVGs directamente en tu HTML anteriormente requería pasos extra como convertir manualmente el SVG a un componente de Astro o instalar una integración de terceros. Ahora, Astro soporta usar el import por defecto de cualquier archivo .svg como usarías cualquier otro componente .astro. Los componentes SVG automáticamente inlinean un tag <svg> directamente en tu HTML.

Puedes pasar props como width, height, fill, stroke, y cualquier otro atributo aceptado por el elemento nativo <svg>.

src/components/MyAstroComponent.astro
---
import Logo from './path/to/svg/file.svg';
---
<Logo width={64} height={64} fill="currentColor" />

Echa un vistazo a la documentación de componentes SVG para más detalles.

¡Agradecimiento especial a Michael Stramel por su trabajo en esta característica!

Actualizando desde SVG experimental

Si anteriormente estabas usando la API experimental de SVG, debes eliminar el flag experimental de tu archivo astro.config.mjs.

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
// ...
experimental: {
svg: true,
},
});

Ten en cuenta que Astro 5.6 introdujo algunos breaking changes en este flag. Por favor comprueba que tu código está actualizado con la última versión estable de esta API.

Imports de configuración

¡El nuevo módulo virtual astro:config ahora es estable!

El módulo virtual te permite importar un subconjunto de la configuración de Astro, con type-safety en mente. Se exponen dos sub-paths para acceso controlado a tu configuración:

  • astro:config/client: expone información de configuración que es segura de exponer al cliente.
  • astro:config/server: expone información adicional que es segura de exponer al servidor, como rutas de archivos/directorios.

Por ejemplo, ahora puedes construir tus propias utilidades de path sin depender de una integración. Propiedades como base y trailingSlash establecidas en tu configuración pueden importarse y usarse en un archivo .js:

astro.config.mjs
export default defineConfig({
base: "store/",
trailingSlash: "always"
});
src/utils.js
import { trailingSlash, base } from 'astro:config/client';
// This method adds a forward slash to paths, and prepends the `base`
function addForwardSlashAndBase(path) {
let finalPath;
if (trailingSlash === 'always') {
finalPath = path.endsWith('/') ? path : path + '/';
} else {
finalPath = path;
}
if (base !== "/") {
return base + finalPath
}
return finalPath
}

Usa esta utilidad de path que depende de tus ajustes de configuración en todo tu proyecto, por ejemplo, para más control sobre los enlaces de página:

src/pages/index.astro
---
import { addForwardSlashAndBase } from "@src/utils.js";
const cartUrl = addForwardSlashAndBase("cart"); // it will return "store/cart/"
---
<a href={cartUrl}>Cart</a>

¡Configuramos que disfrutarías de esta nueva capacidad para acceder a tus ajustes, con la type safety característica de Astro para ayudarte a hacerlo bien!

Correcciones de bugs

Como siempre, hemos estado trabajando duro en corregir problemas desde el lanzamiento 5.6. Consulta el changelog para todos los detalles.

Comunidad

El core team de Astro es:

Ben Holmes , Caleb Jasik , Chris Swithinbank , Emanuele Stoppa , Erika , Florian Lefebvre , Fuzzy , HiDeoo , Luiz Ferraz , Matt Kane , Matthew Phillips , Nate Moore , Reuben Tier , Sarah Rainsberger , and Yan Thomas .

Gracias a todos los demás contribuidores que ayudaron a hacer posible Astro 5.7, incluyendo: Roberto Molina, Junseong Park, ryu, Martin Trapp, Michael Stramel, Armand Philippot, Nin3, viniciusdeliz, Juan Diaz, Marcos Corrochano Arroyo, Paul Valladares, Bugo, liruifengv, Thomas Bonnet, Ming-jun Lu, CHEZ, omoyx, emily-shen, Ariel K, Maciek Palmowski, Matthew Justice, Adam Matthiesen, y Louis Escher.

¡Esperamos ver qué construís con Astro 5.7! Si tienes preguntas, comentarios, o solo quieres decir hola, pásate por el Astro Discord.