Islas de servidor
Las server islands te permiten renderizar bajo demanda "islands" dinámicas o personalizadas individualmente, sin sacrificar el rendimiento del resto de la página.
Esto significa que tu visitante verá las partes más importantes de tu página más rápido, y permite que tu contenido principal se cachee más agresivamente, proporcionando un rendimiento más rápido.
Componentes de server island
Sección titulada “Componentes de server island”Una server island es un componente de Astro renderizado en el servidor normal al que se le indica retrasar el renderizado hasta que sus contenidos estén disponibles.
Tu página se renderizará inmediatamente con cualquier contenido de fallback especificado como placeholder. Luego, el contenido propio del componente se obtiene en el cliente y se muestra cuando está disponible.
Con un adaptador instalado para realizar el renderizado diferido, añade la directiva server:defer a cualquier componente en tu página para convertirlo en su propia island:
---import Avatar from '../components/Avatar.astro';---<Avatar server:defer />Estos componentes pueden hacer cualquier cosa que normalmente harías en una página renderizada bajo demanda usando un adaptador, como obtener contenido, y acceder a cookies:
---import { getUserAvatar } from '../sessions';const userSession = Astro.cookies.get('session');const avatarURL = await getUserAvatar(userSession);---<img alt="User avatar" src={avatarURL} />Pasar props a server islands
Sección titulada “Pasar props a server islands”Las props proporcionadas a los componentes de server island deben ser serializables: capaces de ser traducidas a un formato adecuado para transferencia por red, o almacenamiento. Además, Astro no serializa todos los tipos de estructuras de datos serializables. Por lo tanto, hay algunas limitaciones sobre qué puede pasarse como props a una server island.
En particular, las funciones no pueden pasarse a componentes marcados con server:defer ya que no pueden serializarse. Los objetos con referencias circulares tampoco son serializables.
Se admiten los siguientes tipos de props:
objeto plano, número, cadena de texto, Array, Map, Set, RegExp, Date, BigInt, URL, Uint8Array, Uint16Array, Uint32Array e Infinity
Contenido de fallback de server island
Sección titulada “Contenido de fallback de server island”Al usar el atributo server:defer en un componente para retrasar su renderizado, puedes "slotear" contenido de carga por defecto usando el slot nombrado "fallback" incluido.
Tu contenido de fallback se renderizará junto con el resto de la página inicialmente en la carga de la página y será reemplazado por el contenido de tu componente cuando esté disponible.
Para añadir contenido de fallback, añade slot="fallback" en un hijo (otros componentes o elementos HTML) pasado a tu componente de server island:
---import Avatar from '../components/Avatar.astro';import GenericAvatar from '../components/GenericAvatar.astro';---<Avatar server:defer> <GenericAvatar slot="fallback" /></Avatar>Este contenido de fallback puede ser cosas como:
- Un avatar genérico en lugar del propio del usuario.
- UI placeholder como mensajes personalizados.
- Indicadores de carga como spinners.
Cómo funciona
Sección titulada “Cómo funciona”La implementación de server islands ocurre principalmente en el momento del build donde el contenido del componente se intercambia por un pequeño script.
Cada una de las islands marcadas con server:defer se separa en su propia ruta especial que el script obtiene en tiempo de ejecución. Cuando Astro construye tu sitio omitirá el componente e inyectará un script en su lugar, y cualquier contenido que hayas marcado con slot="fallback".
Cuando la página se carga en el navegador, estos componentes se solicitarán a un endpoint especial que los renderiza y devuelve el HTML. Esto significa que los usuarios verán las partes más críticas de la página instantáneamente. El contenido de fallback será visible por un breve periodo de tiempo antes de que las islands dinámicas se carguen.
Cada island se carga independientemente del resto. Esto significa que una island más lenta no retrasará que el resto de tu contenido personalizado esté disponible.
Este patrón de renderizado fue construido para ser portable. No depende de ninguna infraestructura de servidor por lo que funcionará con cualquier host que tengas, desde un servidor Node.js en un contenedor Docker hasta el proveedor serverless de tu elección.
Almacenamiento en caché
Sección titulada “Almacenamiento en caché”Los datos para las server islands se recuperan vía una petición GET, pasando las props como un string encriptado en la query de la URL. Esto permite cachear datos con el encabezado HTTP Cache-Control usando directivas Cache-Control estándar.
Sin embargo, el navegador limita las URLs a una longitud máxima de 2048 bytes por razones prácticas y para evitar causar problemas de denegación de servicio. Si tu query string causa que tu URL exceda este límite, Astro enviará en su lugar una petición POST que contiene todas las props en el body.
Las peticiones POST no son cacheadas por los navegadores porque se usan para enviar datos, y podrían causar problemas de integridad de datos o seguridad. Por lo tanto, cualquier lógica de caché existente en tu proyecto se romperá. Siempre que sea posible, pasa solo las props necesarias a tus server islands y evita enviar objetos de datos completos y arrays para mantener tu query pequeña.
Acceder a la URL de la página en una server island
Sección titulada “Acceder a la URL de la página en una server island”En la mayoría de los casos, tu componente de server island puede obtener información sobre la página que lo renderiza pasando props como en componentes normales.
Sin embargo, las server islands se ejecutan en su propio contexto aislado fuera de la petición de la página. Astro.url y Astro.request.url en un componente de server island ambos devuelven una URL que se ve como /_server-islands/Avatar en lugar de la URL de la página actual en el navegador. Además, si estás pre-renderizando la página no tendrás acceso a información como los parámetros de query para pasar como props.
Para acceder a información de la URL de la página, puedes comprobar el encabezado Referer, que contendrá la dirección de la página que está cargando la island en el navegador:
---const referer = Astro.request.headers.get("Referer");
if (!referer) { throw new Error("Referer header is missing");}
const url = new URL(referer);const productId = url.searchParams.get("product");---Reutilizar la clave de encriptación
Sección titulada “Reutilizar la clave de encriptación”Astro usa cryptography para encriptar las props pasadas a las server islands, protegiendo datos sensibles de exposición accidental. Esta encriptación depende de una clave nueva y aleatoria que se genera en cada build y se embebe en el bundle del servidor.
La mayoría de los hosts de despliegue manejarán mantener tu frontend y backend sincronizados automáticamente. Sin embargo, puede que necesites una clave de encriptación constante si estás usando despliegues rolling, hosting multi-región o un CDN que cachea páginas que contienen server islands.
En entornos con despliegues rolling (p. ej., Kubernetes) donde tus assets de frontend (que encriptan props) y tus funciones de backend (que desencriptan props) pueden estar usando temporalmente claves diferentes, o cuando un CDN todavía está sirviendo páginas construidas con una clave antigua, las props encriptadas pasadas a tu server island no pueden desencriptarse.
En estas situaciones, usa el CLI de Astro para generar una clave de encriptación reutilizable y codificada para establecer como variable de entorno en tu entorno de build:
astro create-keyUsa este valor para configurar la variable de entorno ASTRO_KEY (p. ej. en un archivo .env) e inclúyelo en tu configuración de build de CI/CD o de tu host. Esto asegura que la misma clave se reutilice siempre en el bundle generado para que la encriptación y desencriptación permanezcan sincronizadas.