Saltar al contenido

Actualizar a Astro v5

Esta guía te ayudará a migrar de Astro v4 a Astro v5.

¿Necesitas actualizar un proyecto anterior a v4 primero? Consulta nuestra guía de migración anterior.

¿Necesitas ver la documentación de v4? Visita esta versión anterior del sitio de documentación (snapshot v4.16 sin mantenimiento).

Actualiza la versión de Astro de tu proyecto a la última versión usando tu gestor de paquetes:

Ventana de la terminal
# Upgrade Astro and official integrations together
npx @astrojs/upgrade

También puedes actualizar tus integraciones de Astro manualmente si es necesario, y también podrías necesitar actualizar otras dependencias en tu proyecto.

Astro v5.0 incluye posibles cambios importantes, así como la remoción y deprecación de algunas funcionalidades.

Si tu proyecto no funciona como se espera después de actualizar a v5.0, consulta esta guía para una descripción general de todos los cambios importantes e instrucciones sobre cómo actualizar tu código base.

Consulta el changelog de Astro para las notas de versión completas.

Cualquier actualización mayor de las dependencias de Astro puede causar cambios importantes en tu proyecto.

Astro v5.0 actualiza a Vite v6.0 como servidor de desarrollo y bundler de producción.

Si estás usando plugins, configuración, o APIs específicas de Vite, consulta la guía de migración de Vite para sus cambios importantes y actualiza tu proyecto según sea necesario.

En Astro v4.x, Astro realizaba el manejo interno de JSX para la integración @astrojs/mdx.

Astro v5.0 mueve esta responsabilidad de manejar y renderizar JSX y MDX al paquete @astrojs/mdx directamente. Esto significa que Astro 5.0 ya no es compatible con versiones anteriores de la integración MDX.

Si tu proyecto incluye archivos .mdx, debes actualizar @astrojs/mdx a la última versión (v4.0.0) para que tu JSX pueda ser manejado correctamente por la integración.

Si estás usando un MDX server renderer con la Astro Container API experimental debes actualizar el import para reflejar la nueva ubicación:

import mdxRenderer from "astro/jsx/server.js";
import mdxRenderer from "@astrojs/mdx/server.js";
Aprende más sobre cómo usar MDX en tu proyecto.

Las siguientes funcionalidades ahora se consideran legacy. Deberían funcionar normalmente pero ya no se recomiendan y están en modo mantenimiento. No recibirán futuras mejoras y la documentación no se actualizará. Estas funcionalidades eventualmente serán deprecadas y luego removidas por completo.

En Astro 4.x, las content collections se definían, consultaban y renderizaban usando la API de Content Collections introducida por primera vez en Astro v2.0. Todas las entradas de colección eran archivos locales dentro de la carpeta reservada src/content/. Adicionalmente, la convención de nombres de archivo de Astro para excluir la construcción de páginas individuales estaba integrada en la API de Content Collections.

Astro 5.0 introduce una nueva versión de content collections usando la Content Layer API que trae varias mejoras de rendimiento y funcionalidades añadidas. Aunque las colecciones antiguas (legacy) y nuevas (Content Layer API) pueden coexistir en esta versión, hay posibles cambios importantes para las colecciones legacy existentes.

Esta versión también elimina la opción de prefijar los nombres de archivo de las entradas de colección con un guion bajo (_) para prevenir la construcción de una ruta.

Recomendamos convertir cualquier colección existente a la nueva Content Layer API tan pronto como puedas y hacer cualquier colección nueva usando la Content Layer API.

Si no puedes convertir tus colecciones, entonces consulta los cambios importantes de las colecciones legacy para ver si tus colecciones existentes están afectadas y requieren actualización.

Si no puedes hacer ningún cambio a tus colecciones en este momento, puedes habilitar el flag legacy.collections que te permitirá mantener tus colecciones en su estado actual hasta que el flag legacy ya no se soporte.

Aprende más sobre las content collections actualizadas.

Consulta las instrucciones a continuación para actualizar una content collection existente (type: 'content' o type: 'data') para usar la Content Layer API.

Instrucciones paso a paso para actualizar una colección
  1. Mueve el archivo de configuración de contenido. Este archivo ya no vive dentro de la carpeta src/content/. Este archivo debería ahora existir en src/content.config.ts.

  2. Edita la definición de la colección. Tu colección actualizada requiere un loader que indica tanto una carpeta para la ubicación de tu colección (base) como un pattern definiendo los nombres de archivo y extensiones de las entradas de colección a coincidir. (Podrías necesitar actualizar el ejemplo a continuación según corresponda. Puedes usar globster.xyz para comprobar tu glob pattern.) La opción para seleccionar un type de colección ya no está disponible.

    src/content.config.ts
    import { defineCollection, z } from 'astro:content';
    import { glob } from 'astro/loaders';
    const blog = defineCollection({
    // For content layer you no longer define a `type`
    type: 'content',
    loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/data/blog" }),
    schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    }),
    });
  3. Cambia las referencias de slug a id. Las colecciones de content layer no tienen un campo reservado slug. En su lugar, todas las colecciones actualizadas tendrán un id:

    src/pages/[slug].astro
    ---
    export async function getStaticPaths() {
    const posts = await getCollection('blog');
    return posts.map((post) => ({
    params: { slug: post.slug },
    params: { slug: post.id },
    props: post,
    }));
    }
    ---

    También puedes actualizar los nombres de archivo de enrutamiento dinámico para coincidir con el valor del parámetro cambiado de getStaticPaths().

  4. Cambia a la nueva función render(). Las entradas ya no tienen un método render(), ya que ahora son objetos simples serializables. En su lugar, importa la función render() desde astro:content.

    src/pages/index.astro
    ---
    import { getEntry, render } from 'astro:content';
    const post = await getEntry('blog', params.slug);
    const { Content, headings } = await post.render();
    const { Content, headings } = await render(post);
    ---
    <Content />
Cambios importantes a colecciones legacy de content y data
Sección titulada “Cambios importantes a colecciones legacy de content y data”

Por defecto, las colecciones que usan la antigua propiedad type (content o data) y no definen un loader ahora se implementan internamente usando el loader glob() integrado de la Content Layer API, con manejo extra de compatibilidad con versiones anteriores.

Adicionalmente, existe compatibilidad con versiones anteriores temporal para mantener el archivo de configuración de contenido en su ubicación original de src/content/config.ts.

Esta implementación de compatibilidad con versiones anteriores es capaz de emular la mayoría de las funcionalidades de las colecciones legacy y permitirá que muchas colecciones legacy continúen funcionando incluso sin actualizar tu código. Sin embargo, hay algunas diferencias y limitaciones que pueden causar cambios importantes en las colecciones existentes:

  • En versiones anteriores de Astro, se generaban colecciones para todas las carpetas en src/content/, incluso si no estaban definidas en src/content/config.ts. Este comportamiento ahora está deprecado, y las colecciones deberían siempre definirse en src/content.config.ts. Para colecciones existentes, estas pueden ser solo declaraciones vacías (ej. const blog = defineCollection({})) y Astro definirá implícitamente tu colección legacy de una manera que es compatible con el nuevo comportamiento de carga.
  • El campo especial layout no se soporta en entradas de colección Markdown. Esta propiedad está destinada solo para archivos de página independientes ubicados en src/pages/ y no es probable que esté en tus entradas de colección. Sin embargo, si estabas usando esta propiedad, ahora debes crear rutas dinámicas que incluyan el estilo de tu página.
  • El orden de clasificación de las colecciones generadas es no determinista y dependiente de la plataforma. Esto significa que si estás llamando getCollection(), el orden en que se retornan las entradas puede ser diferente al de antes. Si necesitas un orden específico, debes clasificar las entradas de colección tú mismo.
  • image().refine() no se soporta. Si necesitas validar las propiedades de una imagen necesitarás hacer esto en runtime en tu página o componente.
  • El argumento key de getEntry(collection, key) está tipado como string, en lugar de tener tipos para cada entrada.
  • Anteriormente al llamar getEntry(collection, key) con un string estático como key, el tipo de retorno no era nullable. El tipo ahora incluye undefined así que debes comprobar si la entrada está definida antes de usar el resultado o tendrás errores de tipo.

Si aún no estás listo para actualizar tus colecciones existentes, puedes habilitar el flag legacy.collections y tus colecciones existentes continuarán funcionando como antes.

Las siguientes funcionalidades deprecadas ya no se soportan y ya no se documentan. Actualiza tu proyecto en consecuencia.

Algunas funcionalidades deprecadas pueden continuar funcionando temporalmente hasta que sean completamente removidas. Otras pueden silenciosamente no tener efecto, o lanzar un error pidiéndote que actualices tu código.

En Astro v4.x, podías usar Astro.glob() en tus componentes .astro para consultar múltiples archivos en tu proyecto. Esto tenía algunas limitaciones (dónde se podía usar, rendimiento, etc.), y usar funciones de consulta de la Content Collections API o el propio import.meta.glob() de Vite a menudo proporcionaba más funcionalidad y flexibilidad.

Astro 5.0 deprecá Astro.glob() en favor de usar getCollection() para consultar tus colecciones, y import.meta.glob() para consultar otros archivos fuente en tu proyecto.

Reemplaza todo el uso de Astro.glob() con import.meta.glob(). Ten en cuenta que import.meta.glob() ya no retorna un Promise, así que podrías tener que actualizar tu código en consecuencia. No deberías requerir ninguna actualización a tus glob patterns.

src/pages/blog.astro
---
const posts = await Astro.glob('./posts/*.md');
const posts = Object.values(import.meta.glob('./posts/*.md', { eager: true }));
---
{posts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}

Donde sea apropiado, considera usar content collections para organizar tu contenido, que tiene sus propias funciones de consulta más nuevas y con mejor rendimiento.

También podrías querer considerar usar paquetes glob de NPM, como fast-glob.

En Astro v4.x, podías optar por crear un archivo separado para cada ruta definida en el proyecto, reflejando tu directorio src/pages/ en la carpeta de build. Por defecto, Astro emitía un único archivo entry.mjs, que era responsable de emitir la página renderizada en cada petición.

Astro v5.0 elimina la opción para excluirse del comportamiento por defecto. Este comportamiento es ahora estándar, y no configurable.

Elimina la propiedad functionPerRoute de tu configuración de adapterFeatures. Ya no está disponible.

my-adapter.mjs
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js',
adapterFeatures: {
functionPerRoute: true
}
});
},
},
};
}
Aprende más sobre la Adapter API para construir integraciones de adapter.

Deprecado: routes en el hook astro:build:done (Integration API)

Sección titulada “Deprecado: routes en el hook astro:build:done (Integration API)”

En Astro v4.x, las integraciones accedían a las rutas desde el hook astro:build:done.

Astro v5.0 deprecá el array routes pasado a este hook. En su lugar, expone un nuevo hook astro:routes:resolved que se ejecuta antes de astro:config:done, y cada vez que una ruta cambia en desarrollo. Tiene todas las mismas propiedades de la lista deprecada de routes, excepto distURL que solo está disponible durante el build.

Elimina cualquier instancia de routes pasada a astro:build:done y reemplázala con el nuevo hook astro:routes:resolved. Accede a distURL en el mapa assets recién expuesto:

my-integration.mjs
const integration = () => {
let routes
return {
name: 'my-integration',
hooks: {
'astro:routes:resolved': (params) => {
routes = params.routes
},
'astro:build:done': ({
routes
assets
}) => {
for (const route of routes) {
const distURL = assets.get(route.pattern)
if (distURL) {
Object.assign(route, { distURL })
}
}
console.log(routes)
}
}
}
}
Aprende más sobre el hook astro:routes:resolved de la Integration API para construir integraciones.

Las siguientes funcionalidades han sido ahora enteramente removidas del código base y ya no se pueden usar. Algunas de estas funcionalidades pueden haber continuado funcionando en tu proyecto incluso después de su deprecación. Otras pueden haber silenciosamente no tenido efecto.

Los proyectos que ahora contienen estas funcionalidades removidas no podrán construirse, y ya no habrá documentación de soporte pidiéndote que elimines estas funcionalidades.

En Astro v4.x, Lit era una librería de framework mantenida por el núcleo a través del paquete @astrojs/lit.

Astro v5.0 elimina la integración y no recibirá más actualizaciones para compatibilidad con 5.x y superior.

Puedes continuar usando Lit para componentes de cliente añadiendo una etiqueta script del lado del cliente. Por ejemplo:

<script>
import "../components/MyTabs";
</script>
<my-tabs title="These are my tabs">...</my-tabs>

Si estás interesado en mantener una integración de Lit tú mismo, podrías querer usar la última versión publicada de @astrojs/lit como punto de partida y actualizar los paquetes relevantes.

En Astro v4.x, Astro proporcionaba tres modos de renderizado output: 'static', 'hybrid', y 'server'

Astro v5.0 fusiona las configuraciones output: 'hybrid' y output: 'static' en una sola configuración (ahora llamada 'static') que funciona de la misma manera que la anterior opción hybrid.

Ya no es necesario especificar output: 'hybrid' en tu configuración de Astro para usar páginas renderizadas en el servidor. El nuevo output: 'static' tiene esta capacidad incluida.

Astro ahora te permitirá automáticamente excluirte del prerendering en tu sitio estático sin necesidad de cambiar tu configuración de output. Cualquier ruta de página o endpoint puede incluir export const prerender = false para ser renderizado en el servidor bajo demanda, mientras que el resto de tu sitio se genera estáticamente.

Si tu proyecto usaba renderizado hybrid, ahora debes eliminar la opción output: 'hybrid' de tu configuración de Astro ya que ya no existe. Sin embargo, no se requieren otros cambios en tu proyecto, y no deberías tener cambios importantes. El comportamiento anterior de 'hybrid' es ahora el por defecto, bajo un nuevo nombre 'static'.

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
output: 'hybrid',
});

Si estabas usando la opción output: 'static' (por defecto), puedes continuar usándola como antes. Por defecto, todas tus páginas continuarán siendo prerenderizadas y tendrás un sitio completamente estático. No deberías tener cambios importantes en tu proyecto.

Un adapter sigue siendo necesario para desplegar un proyecto de Astro con cualquier página renderizada en el servidor, sin importar qué modo de output use tu proyecto. No incluir un adapter resultará en una advertencia en desarrollo y un error en el build.

Aprende más sobre renderizado bajo demanda en Astro.

Removido: soporte para valores dinámicos de prerender en rutas

Sección titulada “Removido: soporte para valores dinámicos de prerender en rutas”

En Astro 4.x, las variables de entorno podían usarse para establecer dinámicamente el valor de los exports de prerender en las rutas, por ejemplo export const prerender = import.meta.env.SOME_VAR.

Astro v5.0 elimina el soporte para valores dinámicos en los exports de prerender. Solo los valores estáticos true y false son soportados.

  1. Elimina cualquier export dinámico de prerender en tus rutas:

    src/pages/blog/[slug].astro
    ---
    export const prerender = import.meta.env.SOME_VAR;
    ---
  2. Usa una integración de Astro en tu archivo astro.config.mjs para establecer valores de prerender que necesiten ser dinámicos en el hook "astro:route:setup":

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import { loadEnv } from 'vite';
    export default defineConfig({
    integrations: [
    {
    name: 'set-prerender',
    hooks: {
    'astro:route:setup': ({ route }) => {
    // Load environment variables from .env files (if needed)
    const { PRERENDER } = loadEnv(process.env.NODE_ENV, process.cwd(), '');
    // Find routes matching the expected filename.
    if (route.component.endsWith('/blog/[slug].astro')) {
    // Set the prerender value on routes as needed.
    route.prerender = PRERENDER;
    }
    },
    },
    }
    ],
    });

En Astro 4.x, podías configurar image.service: squooshImageService() para usar Squoosh para transformar tus imágenes en lugar de Sharp. Sin embargo, la librería subyacente libsquoosh ya no se mantiene y tiene problemas de memoria y rendimiento.

Astro 5.0 elimina el servicio de optimización de imágenes Squoosh por completo.

Para cambiar al servicio de imágenes Sharp integrado, elimina el import de squooshImageService de tu configuración de Astro. Por defecto, usarás Sharp para astro:assets.

astro.config.mjs
import { squooshImageService } from "astro/config";
import { defineConfig } from "astro/config";
export default defineConfig({
image: {
service: squooshImageService()
}
});

Si estás usando un gestor de paquetes estricto como pnpm, podrías necesitar instalar el paquete sharp manualmente para usar el servicio de imágenes Sharp, aunque está integrado en Astro por defecto.

Si tu adapter no soporta la optimización de imágenes Sharp integrada de Astro, puedes configurar un servicio de imágenes no-op para permitirte usar los componentes <Image /> y <Picture />.

Alternativamente, podrías querer considerar un servicio de imágenes Squoosh mantenido por la comunidad si no puedes usar el servicio de imágenes Sharp.

Si tu adapter previamente precisó su estado de compatibilidad con Squoosh, deberías ahora eliminar esta información de la configuración de tu adapter.

my-adapter.mjs
supportedAstroFeatures: {
assets: {
isSquooshCompatible: true
}
}

En Astro v4.x, @types/astro.ts exponía todos los tipos públicamente a los usuarios, independientemente de si aún se usaban activamente o solo estaban destinados al uso interno.

Astro v5.0 refactoriza este archivo para eliminar tipos obsoletos e internos. Este refactor trae mejoras a tu editor (ej. completions más rápidas, menor uso de memoria, y opciones de completion más relevantes). Sin embargo, este refactor puede causar errores en algunos proyectos que han estado dependiendo de tipos que ya no están disponibles públicamente.

Elimina cualquier tipo que ahora cause errores en tu proyecto ya que ya no tienes acceso a ellos. Estos son principalmente APIs que han sido previamente deprecadas y removidas, pero también pueden incluir tipos que ahora son internos.

Los siguientes flags experimentales han sido removidos en Astro v5.0 y estas funcionalidades están disponibles para su uso:

  • env
  • serverIslands

Adicionalmente, los siguientes flags experimentales han sido removidos y son ahora el comportamiento por defecto o recomendado en Astro v5.0.

Los siguientes flags experimentales han sido removidos y sus funcionalidades correspondientes no son parte de Astro v5.0.

  • contentCollectionsCache

Elimina estos flags experimentales si los estabas usando previamente, y mueve tu configuración de env a la raíz de tu configuración de Astro:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
directRenderScript: true,
globalRoutePriority: true,
contentLayer: true,
serverIslands: true,
contentCollectionsCache: true,
env: {
schema: {...}
}
},
env: {
schema: {...}
}
})

Estas funcionalidades están todas disponibles por defecto en Astro v5.0.

Lee sobre estas emocionantes funcionalidades y más en el post del blog de v5.0.

Algunos comportamientos por defecto han cambiado en Astro v5.0 y el código de tu proyecto podría necesitar actualización para tener en cuenta estos cambios.

En la mayoría de los casos, la única acción necesaria es revisar el despliegue de tu proyecto existente y asegurar que continúa funcionando como esperas, haciendo actualizaciones a tu código según sea necesario. En algunos casos, puede haber una configuración que te permita continuar usando el comportamiento por defecto anterior.

La protección CSRF ahora está activada por defecto

Sección titulada “La protección CSRF ahora está activada por defecto”

En Astro v4.x, el valor por defecto de security.checkOrigin era false. Anteriormente, tenías que establecer explícitamente este valor a true para habilitar la protección contra Cross-Site Request Forgery (CSRF).

Astro v5.0 cambia el valor por defecto de esta opción a true, y comprobará automáticamente que el header “origin” coincide con la URL enviada por cada petición en páginas renderizadas bajo demanda.

Si habías configurado previamente security.checkOrigin: true, ya no necesitas esta línea en tu configuración de Astro. Este es ahora el valor por defecto.

Para deshabilitar este comportamiento, debes establecer explícitamente security.checkOrigin: false.

astro.config.mjs
export default defineConfig({
output: "server",
security: {
checkOrigin: false
}
})

Orden de prioridad de rutas para rutas inyectadas y redirecciones

Sección titulada “Orden de prioridad de rutas para rutas inyectadas y redirecciones”

En Astro v4.x, experimental.globalRoutePriority era un flag opcional que aseguraba que las rutas inyectadas, las rutas basadas en archivos, y las redirecciones se priorizaran todas usando las reglas de orden de prioridad de rutas para todas las rutas. Esto permitía más control sobre el enrutamiento en tu proyecto al no priorizar automáticamente ciertos tipos de rutas y estandarizar el orden de prioridad de rutas.

Astro v5.0 elimina este flag experimental y hace este el nuevo comportamiento por defecto en Astro: las redirecciones y rutas inyectadas ahora se priorizan igual junto con las rutas basadas en archivos del proyecto.

Ten en cuenta que este ya era el comportamiento por defecto en Starlight, y no debería afectar a los proyectos de Starlight actualizados.

Si tu proyecto incluye rutas inyectadas o redirecciones, por favor verifica que tus rutas están construyendo las URLs de página como se espera. Un ejemplo del nuevo comportamiento esperado se muestra a continuación.

En un proyecto que contiene las siguientes rutas:

  • Ruta basada en archivo: /blog/post/[pid]
  • Ruta basada en archivo: /[page]
  • Ruta inyectada: /blog/[...slug]
  • Redirección: /blog/tags/[tag] -> /[tag]
  • Redirección: /posts -> /blog

Las siguientes URLs se construirán (en lugar de seguir el orden de prioridad de rutas de Astro v4.x):

  • /blog/tags/astro es construido por la redirección a /tags/[tag] (en lugar de la ruta inyectada /blog/[...slug])
  • /blog/post/0 es construido por la ruta basada en archivo /blog/post/[pid] (en lugar de la ruta inyectada /blog/[...slug])
  • /posts es construido por la redirección a /blog (en lugar de la ruta basada en archivo /[page])

En caso de colisiones de rutas, donde dos rutas de igual prioridad intentan construir la misma URL, Astro registrará una advertencia identificando las rutas en conflicto.

Las etiquetas <script> se renderizan directamente como se declaran

Sección titulada “Las etiquetas <script> se renderizan directamente como se declaran”

En Astro v4.x, experimental.directRenderScript era un flag opcional para renderizar directamente los <scripts> como se declaraban en los archivos .astro (incluyendo funcionalidades existentes como TypeScript, importación de node_modules, y deduplicación de scripts). Esta estrategia prevenía que los scripts se ejecutaran en lugares donde no se usaban. Adicionalmente, los scripts renderizados condicionalmente eran previamente inlineados implícitamente, como si una directiva is:inline se añadiera automáticamente a ellos.

Astro 5.0 elimina este flag experimental y hace este el nuevo comportamiento por defecto en Astro: los scripts ya no se hoistean al <head>, múltiples scripts en una página ya no se bundleean juntos, y una etiqueta <script> puede interferir con el estilo CSS. Adicionalmente, los scripts renderizados condicionalmente ya no se inlinean implícitamente.

Por favor revisa tus etiquetas <script> y asegúrate de que se comportan como deseas.

Si previamente tenías etiquetas <script> renderizadas condicionalmente, necesitarás añadir un atributo is:inline para preservar el mismo comportamiento que antes:

src/components/MyComponent.astro
---
type Props = {
showAlert: boolean
}
const { showAlert } = Astro.props;
---
{
showAlert && <script is:inline>alert("Some very important code!!")</script>
}

Los siguientes cambios se consideran cambios importantes en Astro v5.0. Los cambios importantes pueden o no proporcionar compatibilidad con versiones anteriores temporal. Si estabas usando estas funcionalidades, podrías tener que actualizar tu código como se recomienda en cada entrada.

En Astro 4.x, la API de View Transitions de Astro incluía un componente router <ViewTransitions /> para habilitar el enrutamiento del lado del cliente, transiciones de página, y más.

Astro 5.0 renombra este componente a <ClientRouter /> para aclarar el rol del componente dentro de la API. Esto hace más claro que las funcionalidades que obtienes del componente de enrutamiento <ClientRouter /> de Astro son ligeramente diferentes del router MPA nativo basado en CSS.

Ninguna funcionalidad ha cambiado. Este componente solo ha cambiado su nombre.

Reemplaza todas las ocurrencias del import y componente ViewTransitions con ClientRouter:

src/layouts/MyLayout.astro
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
<html>
<head>
...
<ViewTransitions />
<ClientRouter />
</head>
</html>

En Astro v4.x, Astro dependía de un archivo src/env.d.ts para la inferencia de tipos y la definición de módulos para funcionalidades que dependían de tipos generados.

Astro 5.0 en su lugar usa un archivo .astro/types.d.ts para la inferencia de tipos, y ahora recomienda configurar include y exclude en tsconfig.json para beneficiarse de los tipos de Astro y evitar comprobar archivos construidos.

Ejecutar astro sync ya no crea ni actualiza src/env.d.ts ya que no se requiere para la comprobación de tipos en proyectos estándar de Astro.

Para actualizar tu proyecto a las configuraciones recomendadas de TypeScript de Astro, añade las siguientes propiedades include y exclude a tu tsconfig.json existente:

tsconfig.json
{
"extends": "astro/tsconfigs/base",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}

Ten en cuenta que src/env.d.ts solo es necesario si has añadido configuraciones personalizadas, o si no estás usando un archivo tsconfig.json.

Sección titulada “Cambiado: Las Actions enviadas por formularios HTML ya no usan redirecciones con cookies”

En Astro 4.x, las actions llamadas desde un formulario HTML disparaban una redirección con el resultado reenviado usando cookies. Esto causaba problemas para errores de formularios grandes y valores de retorno que excedían el límite de 4 KB del almacenamiento basado en cookies.

Astro 5.0 ahora renderiza el resultado de una action como un resultado POST sin ningún reenvío. Esto introducirá un diálogo de “confirm form resubmission?” cuando un usuario intenta refrescar la página, aunque ya no impone un límite de 4 KB en el valor de retorno de la action.

Deberías actualizar el manejo de los resultados de actions que depende de redirecciones, y opcionalmente abordar el diálogo de “confirm form resubmission?” con middleware.

Para redirigir a la ruta anterior en caso de error
Sección titulada “Para redirigir a la ruta anterior en caso de error”

Si tu action de formulario HTML está dirigida a una ruta diferente (ej. action={"/success-page" + actions.name}), Astro ya no redirigirá a la ruta anterior en caso de error. Puedes implementar este comportamiento manualmente usando redirecciones desde tu componente Astro. Este ejemplo en su lugar redirige a una nueva ruta en caso de éxito, y maneja los errores en la página actual de lo contrario:

src/pages/newsletter.astro
---
import { actions } from 'astro:actions';
const result = Astro.getActionResult(actions.newsletter);
if (!result?.error) {
// Embed relevant result data in the URL if needed
// example: redirect(`/confirmation?email=${result.data.email}`);
return redirect('/confirmation');
}
---
<form method="POST" action={'/confirmation' + actions.newsletter}>
<label>E-mail <input required type="email" name="email" /></label>
<button>Sign up</button>
</form>
(Opcional) Para eliminar el diálogo de confirmación al refrescar
Sección titulada “(Opcional) Para eliminar el diálogo de confirmación al refrescar”

Para abordar el diálogo de “confirm form resubmission?” al refrescar, o para preservar los resultados de actions entre sesiones, ahora puedes personalizar el manejo de resultados de action desde middleware.

Recomendamos usar un proveedor de almacenamiento de sesiones como se describe en nuestro ejemplo de Netlify Blob. Sin embargo, si prefieres el comportamiento de reenvío con cookies de 4.X y aceptas el límite de 4 KB, puedes implementar el patrón como se muestra en este snippet de ejemplo:

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
// Skip requests for prerendered pages
if (context.isPrerendered) return next();
const { action, setActionResult, serializeActionResult } = getActionContext(context);
// If an action result was forwarded as a cookie, set the result
// to be accessible from `Astro.getActionResult()`
const payload = context.cookies.get('ACTION_PAYLOAD');
if (payload) {
const { actionName, actionResult } = payload.json();
setActionResult(actionName, actionResult);
context.cookies.delete('ACTION_PAYLOAD', { path: '/' });
return next();
}
// If an action was called from an HTML form action,
// call the action handler and redirect with the result as a cookie.
if (action?.calledFrom === 'form') {
const actionResult = await action.handler();
context.cookies.set('ACTION_PAYLOAD', {
actionName: action.name,
actionResult: serializeActionResult(actionResult),
}, {
path: '/',
httpOnly: true,
sameSite: 'lax',
maxAge: 60
});
if (actionResult.error) {
// Redirect back to the previous page on error
const referer = context.request.headers.get('Referer');
if (!referer) {
throw new Error('Internal: Referer unexpectedly missing from Action POST request.');
}
return context.redirect(referer);
}
// Redirect to the destination page on success
return context.redirect(context.originPathname);
}
return next();
})

Cambiado: compiledContent() ahora es una función async

Sección titulada “Cambiado: compiledContent() ahora es una función async”

En Astro 4.x, top level await se incluía en los módulos de Markdown. Esto causaba algunos problemas con servicios de imágenes personalizados e imágenes dentro de Markdown, causando que Node terminara abruptamente sin mensaje de error.

Astro 5.0 hace la propiedad compiledContent() en los imports de Markdown una función async, requiriendo un await para resolver el contenido.

Actualiza tu código para usar await al llamar a compiledContent().

src/pages/post.astro
---
import * as myPost from "../blog/post.md";
const content = myPost.compiledContent();
const content = await myPost.compiledContent();
---
<Fragment set:html={content} />
Lee más sobre la función compiledContent() para retornar Markdown compilado.

Cambiado: astro:content ya no puede usarse en el cliente

Sección titulada “Cambiado: astro:content ya no puede usarse en el cliente”

En Astro 4.x, era posible acceder al módulo astro:content en el cliente.

Astro 5.0 elimina este acceso ya que nunca fue expuesto intencionalmente para uso en el cliente. Usar astro:content de esta manera tenía limitaciones e hinchaba los bundles del cliente.

Si estás usando actualmente astro:content en el cliente, pasa los datos que necesitas a través de props a tus componentes de cliente en su lugar:

src/pages/blog.astro
---
import { getCollection } from 'astro:content';
import ClientComponent from '../components/ClientComponent';
const posts = await getCollection('blog');
const postsData = posts.map(post => post.data);
---
<ClientComponent posts={postsData} />
Lee más sobre la API de astro:content.

Renombrado: nombres de tokens de color del tema css-variables de Shiki

Sección titulada “Renombrado: nombres de tokens de color del tema css-variables de Shiki”

En Astro v4.x, el tema css-variables de Shiki usaba los tokens --astro-code-color-text y --astro-code-color-background para estilizar los colores de primer plano y fondo de los bloques de código respectivamente.

Astro v5.0 los renombra a --astro-code-foreground y --astro-code-background respectivamente para mejor alineación con los valores por defecto de Shiki v1.

Puedes realizar un buscar y reemplazar global en tu proyecto para migrar a los nuevos nombres de tokens.

src/styles/global.css
:root {
--astro-code-color-text: #000;
--astro-code-color-background: #fff;
--astro-code-foreground: #000;
--astro-code-background: #fff;
}

Cambiado: plugin interno de Shiki rehype para resaltar bloques de código

Sección titulada “Cambiado: plugin interno de Shiki rehype para resaltar bloques de código”

En Astro 4.x, el plugin interno de Shiki rehype de Astro resaltaba los bloques de código como HTML.

Astro 5.0 actualiza este plugin para resaltar bloques de código como hast. Esto permite un procesamiento más directo de Markdown y MDX y mejora el rendimiento al construir el proyecto. Sin embargo, esto puede causar problemas con los transformers de Shiki existentes.

Si estás usando transformers de Shiki pasados a markdown.shikiConfig.transformers, debes asegurarte de que no usan el hook postprocess. Este hook ya no se ejecuta en bloques de código en archivos .md y .mdx. (Consulta la documentación de Shiki sobre transformer hooks para más información).

Los bloques de código en archivos .mdoc y el componente integrado <Code /> de Astro no usan el plugin interno de Shiki rehype y no se ven afectados.

Cambiado: Comportamiento automático de charset=utf-8 para páginas Markdown y MDX

Sección titulada “Cambiado: Comportamiento automático de charset=utf-8 para páginas Markdown y MDX”

En Astro 4.0, las páginas Markdown y MDX (ubicadas en src/pages/) respondían automáticamente con charset=utf-8 en el header Content-Type, lo que permitía renderizar caracteres non-ASCII en tus páginas.

Astro 5.0 actualiza el comportamiento para añadir la etiqueta <meta charset="utf-8"> en su lugar, y solo para páginas que no usan la propiedad especial de frontmatter layout de Astro. Similarmente para páginas MDX, Astro solo añadirá la etiqueta si el contenido MDX no importa un componente Layout envolvente.

Si tus páginas Markdown o MDX usan la propiedad de frontmatter layout, o si el contenido de la página MDX importa un componente Layout envolvente, entonces la codificación HTML será manejada por el componente layout designado en su lugar, y la etiqueta <meta charset="utf-8"> no se añadirá a tu página por defecto.

Si necesitas charset=utf-8 para renderizar tu página correctamente, asegúrate de que tus componentes de layout contengan la etiqueta <meta charset="utf-8">. Podrías necesitar añadirla si aún no lo has hecho.

Lee más sobre layouts de Markdown.

Cambiado: metadatos específicos de Astro adjuntados en plugins remark y rehype

Sección titulada “Cambiado: metadatos específicos de Astro adjuntados en plugins remark y rehype”

En Astro 4.x, los metadatos específicos de Astro adjuntados a vfile.data en plugins remark y rehype se adjuntaban en diferentes ubicaciones con nombres inconsistentes.

Astro 5 limpia la API y los metadatos ahora se renombran como se muestra a continuación:

  • vfile.data.__astroHeadings -> vfile.data.astro.headings
  • vfile.data.imagePaths -> vfile.data.astro.imagePaths

El tipo de imagePaths también se ha actualizado de Set<string> a string[]. Los metadatos de vfile.data.astro.frontmatter se dejan sin cambios.

Aunque no consideramos estas APIs públicas, pueden ser accedidas por plugins remark y rehype que quieren reutilizar los metadatos de Astro. Si estás usando estas APIs, asegúrate de acceder a ellas en las nuevas ubicaciones.

Cambiado: configuración del endpoint de imágenes

Sección titulada “Cambiado: configuración del endpoint de imágenes”

En Astro 4.x, podías configurar un endpoint en tu configuración de image para usarlo en la optimización de imágenes.

Astro 5.0 te permite personalizar una route y un entrypoint de la configuración image.endpoint. Esto puede ser útil en situaciones de nicho donde la ruta por defecto /_image entra en conflicto con una ruta existente o con la configuración de tu servidor local.

Si habías personalizado previamente image.endpoint, mueve este endpoint a la nueva propiedad endpoint.entrypoint. Opcionalmente, puedes personalizar una route:

astro.config.mjs
import { defineConfig } from "astro/config";
defineConfig({
image: {
endpoint: './src/image-endpoint.ts',
endpoint: {
route: "/image",
entrypoint: "./src/image_endpoint.ts"
}
},
})

Cambiado: comportamiento de resolución de build.client y build.server

Sección titulada “Cambiado: comportamiento de resolución de build.client y build.server”

En Astro v4.x, las opciones build.client y build.server estaban documentadas para resolverse relativamente desde la opción outDir, pero no siempre funcionaba como se esperaba.

Astro 5.0 arregla el comportamiento para resolver correctamente desde la opción outDir. Por ejemplo, si outDir está configurado a ./dist/nested/, entonces por defecto:

  • build.client se resolverá a <root>/dist/nested/client/
  • build.server se resolverá a <root>/dist/nested/server/

Anteriormente los valores se resolvían incorrectamente:

  • build.client se resolvía a <root>/dist/nested/dist/client/
  • build.server se resolvía a <root>/dist/nested/dist/server/

Si dependías de las rutas de build anteriores, asegúrate de que el código de tu proyecto esté actualizado a las nuevas rutas de build.

Cambiado: las dependencias JS en el archivo de configuración ya no son procesadas por Vite

Sección titulada “Cambiado: las dependencias JS en el archivo de configuración ya no son procesadas por Vite”

En Astro 4.x, las dependencias JS enlazadas localmente (ej. npm link, en un monorepo, etc.) podían usar funcionalidades de Vite como import.meta.glob cuando eran importadas por el archivo de configuración de Astro.

Astro 5 actualiza el flujo de carga de configuración de Astro para ignorar el procesamiento de dependencias JS enlazadas localmente con Vite. Las dependencias que exportan archivos TypeScript crudos no se ven afectadas. En su lugar, estas dependencias JS serán importadas normalmente por el runtime de Node.js de la misma manera que otras dependencias de node_modules.

Este cambio se hizo porque el comportamiento anterior causaba confusión entre los autores de integraciones que probaban contra un paquete que funcionaba localmente, pero no cuando se publicaba. También restringía el uso de dependencias solo CJS porque Vite requería que el código fuera ESM. Aunque este cambio solo afecta a dependencias JS, también se recomienda que los paquetes exporten JavaScript en lugar de TypeScript crudo cuando sea posible para prevenir el uso accidental específico de Vite ya que es un detalle de implementación del flujo de carga de configuración de Astro.

Asegúrate de que tus dependencias JS enlazadas localmente estén construidas antes de ejecutar tu proyecto de Astro. Luego, la carga de configuración debería funcionar como antes.

En Astro v4.x, la URL retornada por paginate() (ej. page.url.next, page.url.first, etc.) no incluía el valor configurado para base en tu configuración de Astro. Tenías que añadir manualmente tu valor configurado de base a la ruta de la URL.

Astro 5.0 incluye automáticamente el valor de base en page.url.

Si estás usando la función paginate() para estas URLs, elimina cualquier valor de base existente ya que ahora se añade por ti:

---
export async function getStaticPaths({ paginate }) {
const astronautPages = [{
astronaut: 'Neil Armstrong',
}, {
astronaut: 'Buzz Aldrin',
}, {
astronaut: 'Sally Ride',
}, {
astronaut: 'John Glenn',
}];
return paginate(astronautPages, { pageSize: 1 });
}
const { page } = Astro.props;
// `base: /'docs'` configured in `astro.config.mjs`
const prev = "/docs" + page.url.prev;
const prev = page.url.prev;
---
<a id="prev" href={prev}>Back</a>
Lee más sobre la paginación en Astro.

Cambiado: valores de atributos HTML no booleanos

Sección titulada “Cambiado: valores de atributos HTML no booleanos”

En Astro v4.x, los atributos HTML no booleanos podían no haber incluido sus valores al renderizarse a HTML.

Astro v5.0 renderiza los valores explícitamente como ="true" o ="false", coincidiendo con el manejo adecuado de atributos en los navegadores.

En los siguientes ejemplos de .astro, solo allowfullscreen es un atributo booleano:

src/pages/index.astro
<!-- `allowfullscreen` is a boolean attribute -->
<p allowfullscreen={true}></p>
<p allowfullscreen={false}></p>
<!-- `inherit` is *not* a boolean attribute -->
<p inherit={true}></p>
<p inherit={false}></p>
<!-- `data-*` attributes are not boolean attributes -->
<p data-light={true}></p>
<p data-light={false}></p>

Astro v5.0 ahora preserva el atributo data completo con su valor al renderizar el HTML de atributos no booleanos:

<p allowfullscreen></p>
<p></p>
<p inherit="true"></p>
<p inherit></p>
<p inherit="false"></p>
<p data-light></p>
<p data-light="true"></p>
<p></p>
<p data-light="false"></p>

Si dependes de valores de atributos, por ejemplo, para localizar elementos o para renderizar condicionalmente, actualiza tu código para coincidir con los nuevos valores de atributos no booleanos:

el.getAttribute('inherit') === ''
el.getAttribute('inherit') === 'false'
el.hasAttribute('data-light')
el.dataset.light === 'true'

En Astro 4.x, era posible reemplazar completamente el objeto locals en middleware, endpoints de API, y páginas al añadir nuevos valores.

Astro 5.0 requiere que añadas valores al objeto locals existente sin eliminarlo. Los locals en middleware, endpoints de API, y páginas, ya no pueden ser completamente sobrescritos.

Donde anteriormente estabas sobrescribiendo el objeto, ahora debes asignar valores a él:

src/middleware.js
ctx.locals = {
Object.assign(ctx.locals, {
one: 1,
two: 2
}
})

En Astro v4.x, los params pasados a getStaticPath() se decodificaban automáticamente usando decodeURIComponent.

Astro v5.0 ya no decodifica el valor de los params pasados a getStaticPaths. Debes decodificarlos manualmente tú mismo si es necesario.

Si dependías previamente de la decodificación automática, usa decodeURI al pasar los params.

src/pages/[id].astro
---
export function getStaticPaths() {
return [
{ params: { id: "%5Bpage%5D" } },
{ params: { id: decodeURI("%5Bpage%5D") } },
]
}
const { id } = Astro.params;
---

Ten en cuenta que el uso de decodeURIComponent se desaconseja para getStaticPaths porque decodifica más caracteres de los que debería, por ejemplo /, ?, # y más.

Cambiado: tipo RouteData reemplazado por IntegrationsRouteData (Integrations API)

Sección titulada “Cambiado: tipo RouteData reemplazado por IntegrationsRouteData (Integrations API)”

En Astro v4.x, el tipo entryPoints dentro de los hooks astro:build:ssr y astro:build:done era RouteData.

En Astro v5.0 el tipo entryPoints es ahora IntegrationRouteData, que contiene un subconjunto del tipo RouteData. Los campos isIndex y fallbackRoutes fueron removidos.

Actualiza tu adapter para cambiar el tipo de entryPoints de RouteData a IntegrationRouteData.

import type {RouteData} from 'astro';
import type {IntegrationRouteData} from "astro"
function useRoute(route: RouteData) {
function useRoute(route: IntegrationRouteData) {
}

Cambiado: distURL ahora es un array (Integrations API)

Sección titulada “Cambiado: distURL ahora es un array (Integrations API)”

En Astro v4.x, RouteData.distURL era undefined o una URL.

Astro v5.0 actualiza la forma de IntegrationRouteData.distURL para ser undefined o un array de URLs. Esto arregla un error previo porque una ruta puede generar múltiples archivos en disco, especialmente cuando se usan rutas dinámicas como [slug] o [...slug].

Actualiza tu código para manejar IntegrationRouteData.distURL como un array.

if (route.distURL) {
if (route.distURL.endsWith('index.html')) {
// do something
}
for (const url of route.distURL) {
if (url.endsWith('index.html')) {
// do something
}
}
}

Cambiado: Argumentos pasados a app.render() (Adapter API)

Sección titulada “Cambiado: Argumentos pasados a app.render() (Adapter API)”

En Astro 4.x, el método app.render() de la Adapter API podía recibir tres argumentos: un request obligatorio, un objeto de opciones o un objeto routeData, y locals.

Astro 5.0 combina estos dos últimos argumentos en un único argumento de opciones llamado renderOptions.

Pasa un objeto como segundo argumento a app.render(), que puede incluir routeData y locals como propiedades.

const response = await app.render(request, routeData, locals);
const response = await app.render(request, {routeData, locals});

Cambiado: Propiedades en supportedAstroFeatures (Adapter API)

Sección titulada “Cambiado: Propiedades en supportedAstroFeatures (Adapter API)”

En Astro 4.x, supportedAstroFeatures, que permite a los autores de adapters especificar qué funcionalidades soporta su integración, incluía una propiedad assets para especificar cuáles de los servicios de imágenes de Astro eran soportados.

Astro 5.0 reemplaza esta propiedad con una propiedad dedicada sharpImageService, usada para determinar si el adapter es compatible con el servicio de imágenes sharp integrado.

v5.0 también añade un nuevo valor limited para las diferentes propiedades de supportedAstroFeatures para adapters, que indica que el adapter es compatible con la funcionalidad, pero con algunas limitaciones. Esto es útil para adapters que soportan una funcionalidad, pero no en todos los casos o con todas las opciones.

Adicionalmente, el valor de las diferentes propiedades en supportedAstroFeatures para adapters ahora puede ser objetos, con propiedades support y message. El contenido de la propiedad message mostrará un mensaje útil en la CLI de Astro cuando el adapter no es compatible con una funcionalidad. Esto es notablemente útil con el nuevo valor limited, para explicar al usuario por qué el soporte es limitado.

Si estabas usando la propiedad assets, elimínala ya que ya no está disponible. Para especificar que tu adapter soporta el servicio de imágenes sharp integrado, reemplázala con sharpImageService.

También podrías querer actualizar tus funcionalidades soportadas con la nueva opción limited e incluir un mensaje sobre el soporte de tu adapter.

my-adapter.mjs
supportedAstroFeatures: {
assets: {
supportKind: "stable",
isSharpCompatible: true,
isSquooshCompatible: true,
},
sharpImageService: {
support: "limited",
message: 'This adapter supports the built-in sharp image service, but with some limitations.'
}
}

Removido: Forma de definición deprecada para dev toolbar apps (Dev Toolbar API)

Sección titulada “Removido: Forma de definición deprecada para dev toolbar apps (Dev Toolbar API)”

En Astro 4.x, al construir una dev toolbar app, aún era posible usar la signature previamente deprecada addDevToolbarApp(string);. Las propiedades id, title, y icon para definir la app se hacían disponibles entonces a través del export por defecto del entrypoint de la app.

Astro 5.0 elimina completamente esta opción en favor de la forma de objeto actual al definir una dev toolbar app en una integración que es más intuitiva y permite a Astro proporcionar mejores errores cuando las toolbar apps fallan al cargar correctamente.

Si estabas usando la forma deprecada, actualiza tu dev toolbar app para usar la nueva forma:

my-integration.mjs
// Old shape
addDevToolbarApp("./my-dev-toolbar-app.mjs");
// New shape
addDevToolbarApp({
id: "my-app",
name: "My App",
icon: "<svg>...</svg>",
entrypoint: "./my-dev-toolbar-app.mjs",
});
my-dev-toolbar-app.mjs
export default {
id: 'my-dev-toolbar-app',
title: 'My Dev Toolbar App',
icon: '🚀',
init() {
// ...
}
}

Removido: configuración de TypeScript durante create-astro

Sección titulada “Removido: configuración de TypeScript durante create-astro”

En Astro v4.x, era posible elegir entre las tres configuraciones de TypeScript de Astro al crear un nuevo proyecto usando create astro, ya fuera respondiendo una pregunta o pasando un flag --typescript asociado con la configuración de TypeScript deseada.

Astro 5.0 actualiza el comando CLI create astro para eliminar la pregunta de TypeScript y su flag --typescript asociado. El preset “strict” es ahora el valor por defecto para todos los nuevos proyectos creados con la línea de comandos y ya no es posible personalizar esto en ese momento. Sin embargo, la plantilla de TypeScript aún puede cambiarse manualmente en tsconfig.json.

Si estabas usando el flag --typescript con create-astro, elimínalo de tu comando.

Ventana de la terminal
npm create astro@latest -- --template <example-name> --typescript strict
npm create astro@latest -- --template <example-name>

¿Conoces un buen recurso para Astro v5.0? Edita esta página y añade un enlace abajo!

Por favor consulta los issues de Astro en GitHub para cualquier problema reportado, o para reportar un issue tú mismo.

Contribuir Comunidad Patrocinar