Saltar al contenido

API de Renderer de Astro

Astro está diseñado para soportar cualquier framework de UI. Esta capacidad está impulsada por renderers, que son integraciones. Consulta la guía de frameworks front-end para aprender cómo usar componentes de UI de diferentes frameworks en Astro.

Un renderer es un tipo especial de integración que le dice a Astro cómo detectar y renderizar sintaxis de componentes que no maneja nativamente, como componentes de frameworks de UI. Un renderer consta de dos partes:

  • un módulo de servidor importado durante desarrollo y builds de producción para renderizar componentes a HTML.
  • un módulo de cliente opcional importado en el navegador para hidratar componentes con directivas de cliente.

Cuando necesitas añadir soporte para una nueva sintaxis de componentes en Astro, crea una integración y llama a addRenderer() en el hook astro:config:setup. Esto te permite definir el entrypoint del servidor que Astro debería usar para renderizar componentes. Opcionalmente, también puedes definir el entrypoint de cliente usado para hidratación.

El siguiente ejemplo muestra cómo registrar un renderer en una integración de Astro:

my-renderer/index.js
export default function createIntegration() {
return {
name: "@example/my-renderer",
hooks: {
"astro:config:setup": ({ addRenderer }) => {
addRenderer({
name: "@example/my-renderer",
clientEntrypoint: "@example/my-renderer/client.js",
serverEntrypoint: "@example/my-renderer/server.js",
});
},
},
};
}

Necesitarás crear un archivo que se ejecute durante el renderizado del lado del servidor y defina cómo renderizar la sintaxis de componentes. El módulo del servidor debe exportar por defecto un objeto que implemente la interfaz SSRLoadedRendererValue.

El siguiente ejemplo muestra un renderer mínimo del lado del servidor implementando check() y renderToStaticMarkup():

my-renderer/server.ts
import type { AstroComponentMetadata, NamedSSRLoadedRendererValue } from 'astro';
async function check(Component: unknown) {
return typeof Component === 'function' && Component.name === 'MyCustomComponent';
}
async function renderToStaticMarkup(
Component: any,
props: Record<string, unknown>,
slots: Record<string, string>,
metadata?: AstroComponentMetadata,
) {
const rendered = Component(props);
return {
attrs: metadata?.hydrate ? { 'data-my-renderer': 'true' } : undefined,
html: `<${rendered.tag}>${rendered.text}${slots.default ?? ''}</${rendered.tag}>`,
};
}
const renderer: NamedSSRLoadedRendererValue = {
name: 'my-renderer',
check,
renderToStaticMarkup,
};
export default renderer;

Cuando tu renderer soporta directivas de cliente, crea un entrypoint de cliente que defina cómo hidratar componentes en el navegador. El módulo de cliente debe exportar por defecto una función que reciba el elemento del island y devuelva una función async de hidratación.

Astro despacha un evento personalizado astro:unmount en el elemento raíz del island cada vez que un island es eliminado de la página. Puedes escuchar este evento en tu entrypoint de cliente para limpiar cualquier estado de la aplicación montada.

El siguiente ejemplo muestra un entrypoint de cliente mínimo que hidrata componentes en el navegador:

my-renderer/client.ts
export default (element: HTMLElement) =>
async (
Component: any,
props: Record<string, unknown>,
slots: Record<string, string>,
{ client }: { client: string },
) => {
const rendered = Component({ ...props, slots });
if (client === 'only') {
element.innerHTML = '';
}
const node = document.createElement(rendered.tag);
node.textContent = rendered.text;
element.appendChild(node);
element.addEventListener('astro:unmount', () => node.remove(), { once: true });
};

Los siguientes tipos pueden importarse desde el módulo astro:

import type {
AstroComponentMetadata,
AstroRenderer,
NamedSSRLoadedRendererValue,
SSRLoadedRenderer,
SSRLoadedRendererValue,
} from "astro";

Tipo: { displayName: string; hydrate?: 'load' | 'idle' | 'visible' | 'media' | 'only'; hydrateArgs?: any; componentUrl?: string; componentExport?: { value: string; namespace?: boolean }; astroStaticSlot: true; }

Contiene información sobre el componente que se está renderizando, incluyendo su directiva de hidratación.

Type: string

Define el nombre del componente, usado para mensajes de error y debugging.

Type: 'load' | 'idle' | 'visible' | 'media' | 'only'

Define la directiva de cliente usada en el componente. Si no se proporciona ningún valor, el componente no será hidratado en el cliente.

Los renderers pueden usar este valor para incluir condicionalmente el estado de hidratación del lado del cliente. Por ejemplo, un renderer puede saltarse la serialización del estado de transferencia para componentes que no serán hidratados:

async function renderToStaticMarkup(Component, props, children, metadata) {
const willHydrate = !!metadata?.hydrate;
// Skip serializing hydration state if the component won't be hydrated
return render(Component, props, { includeTransferState: willHydrate });
}

Type: any

Especifica los argumentos adicionales pasados a la directiva de hidratación.

Por ejemplo, esto podría ser el string de media query para client:media (ej. "(max-width: 768px)") o la pista del renderer para client:only (ej. "react").

Type: string

Define la URL del archivo fuente del componente.

Type: { value: string; namespace?: boolean }

Describe el export del componente que Astro cargará en el cliente para componentes hidratados.

AstroComponentMetadata.componentExport.namespace
Sección titulada “AstroComponentMetadata.componentExport.namespace”

Type: boolean

Indica si el export es un export de namespace.

Type: string

Define el nombre del export (ej. "default" para exports por defecto).

Type: true

Indica que Astro soporta la optimización de slots estáticos para este componente. Los renderers que establecen supportsAstroStaticSlot en true pueden usarlo en combinación con hydrate para determinar cómo renderizar los slots.

Tipo: { name: string; clientEntrypoint?: string | URL; serverEntrypoint: string | URL; }

Describe un renderer de componentes añadido por una integración.

Type: string

Define el nombre público único del renderer.

Type: string | URL

Define la ruta de importación del renderer que se ejecuta en el cliente siempre que se use tu componente.

Type: string | URL

Define la ruta de importación del renderer que se ejecuta durante solicitudes del lado del servidor o builds estáticos siempre que se use tu componente.

Extiende SSRLoadedRendererValue con una propiedad name obligatoria.

Type: Pick<AstroRenderer, ‘name’ | ‘clientEntrypoint’> & { ssr: SSRLoadedRendererValue; }

Describe un renderer disponible para que el servidor lo use. Esto es un subconjunto de AstroRenderer con propiedades adicionales.

Type: SSRLoadedRendererValue

Define las funciones y configuración usadas por el servidor para este framework.

Type: object

Contiene las funciones y configuración necesarias para renderizar componentes en el servidor desde un framework de UI específico.

Type: string

Especifica el identificador de nombre para el renderer.

Tipo: (Component: any, props: any, slots: Record<string, string>, metadata?: AstroComponentMetadata) => Promise<boolean>

Determina si el renderer puede manejar un componente. Esta función se llama para cada renderer registrado hasta que uno devuelva true.

Tipo: (Component: any, props: any, slots: Record<string, string>, metadata?: AstroComponentMetadata) => Promise<{ html: string; attrs?: Record<string, string>; }>

Renderiza un componente del framework en el servidor y devuelve el string HTML resultante junto con cualquier atributo opcional que deba pasarse al entrypoint de cliente.

Type: boolean

Añadido en: astro@2.5.0

Indica si el renderer soporta la optimización de slots estáticos de Astro. Cuando es true, Astro previene la eliminación de slots anidados dentro de islands.

Type: () => string

Añadido en: astro@4.1.0

Devuelve un string HTML para inyectar una vez por página antes del primer componente hidratado manejado por este renderer. Esto es útil para renderers que necesitan configuración de hidratación a nivel de página.

Contribuir Comunidad Patrocinar