Saltar al contenido

Referencia de directivas de plantilla

Las directivas de plantilla son un tipo especial de atributo HTML disponible dentro de cualquier plantilla de componente de Astro (archivos .astro), y algunas también se pueden usar en archivos .mdx.

Las directivas de plantilla se utilizan para controlar el comportamiento de un elemento o componente de alguna manera. Una directiva de plantilla podría habilitar alguna característica del compilador que te facilite la vida (como usar class:list en lugar de class). O bien, una directiva podría indicarle al compilador de Astro que haga algo especial con ese componente (como hidratarlo con client:load).

Esta página describe todas las directivas de plantilla disponibles para ti en Astro, y cómo funcionan.

Para que una directiva de plantilla sea válida, debe:

  • Incluir dos puntos : en su nombre, usando la forma X:Y (ej: client:load).
  • Ser visible para el compilador (ej: <X {...attr}> no funcionaría si attr contuviera una directiva).

Algunas directivas de plantilla, pero no todas, pueden tomar un valor personalizado:

  • <X client:load /> (no toma ningún valor)
  • <X class:list={['some-css-class']} /> (toma un array)

Una directiva de plantilla nunca se incluye directamente en la salida HTML final de un componente.

class:list={...} toma un array de valores de clase y los convierte en una cadena de clases. Esto funciona gracias a la popular biblioteca auxiliar clsx de @lukeed.

class:list toma un array de varios tipos de valores posibles:

  • string: Añadido al elemento class
  • Object: Todas las claves truthy se añaden a la clase del elemento (class)
  • Array: aplanado
  • false, null o undefined: omitido
<!-- This -->
<span class:list={[ 'hello goodbye', { world: true }, [ 'friend' ] ]} />
<!-- Becomes -->
<span class="hello goodbye world friend"></span>

set:html={string} inyecta una cadena HTML en un elemento, de manera similar a establecer el.innerHTML.

¡Astro no escapa automáticamente el valor! Asegúrate de confiar en el valor, o de haberlo escapado manualmente antes de pasarlo a la plantilla. Olvidar hacer esto te expondrá a ataques de Cross Site Scripting (XSS).

---
const rawHTMLString = "Hello <strong>World</strong>"
---
<h1>{rawHTMLString}</h1>
<!-- Output: <h1>Hello &lt;strong&gt;World&lt;/strong&gt;</h1> -->
<h1 set:html={rawHTMLString} />
<!-- Output: <h1>Hello <strong>World</strong></h1> -->

También puedes usar set:html en un <Fragment> para evitar añadir un elemento contenedor innecesario. Esto puede ser especialmente útil al recuperar HTML de un CMS.

---
const cmsContent = await fetchHTMLFromMyCMS();
---
<Fragment set:html={cmsContent}>

set:html={Promise<string>} inyecta una cadena HTML en un elemento que está envuelto en una Promesa (Promise).

Esto se puede usar para inyectar HTML almacenado externamente, como en una base de datos.

---
import api from '../db/api.js';
---
<article set:html={api.getArticle(Astro.props.id)}></article>

set:html={Promise<Response>} inyecta una respuesta (Response) en un elemento.

Esto es muy útil cuando se usa fetch(). Por ejemplo, recuperando entradas antiguas de un generador de sitios estáticos anterior.

<article set:html={fetch('http://example/old-posts/making-soup.html')}></article>

set:html se puede usar en cualquier etiqueta y no tiene que incluir HTML. Por ejemplo, utilízalo con JSON.stringify() en una etiqueta <script> para añadir un esquema JSON-LD a tu página.

<script type="application/ld+json" set:html={JSON.stringify({
"@context": "https://schema.org/",
"@type": "Person",
name: "Houston",
hasOccupation: {
"@type": "Occupation",
name: "Astronaut"
}
})}/>

set:text={string} inyecta una cadena de texto en un elemento, similar a establecer el.innerText. A diferencia de set:html, el valor string que se pasa es escapado automáticamente por Astro.

Esto es equivalente a pasar una variable directamente a una expresión de plantilla (ej: <div>{someText}</div>) y, por lo tanto, esta directiva no se usa comúnmente.

Estas directivas controlan cómo se hidratan los componentes de frameworks de UI en la página.

Por defecto, un componente de framework de UI no se hidrata en el cliente. Si no se proporciona ninguna directiva client:*, su HTML se renderiza en la página sin JavaScript.

Una directiva de cliente solo se puede usar en un componente de framework de UI que se importe directamente en un componente .astro. Las directivas de hidratación no son compatibles cuando se utilizan etiquetas dinámicas y componentes personalizados pasados a través de la propiedad components.

  • Prioridad: Alta
  • Útil para: Elementos de la UI inmediatamente visibles que deben ser interactivos lo antes posible.

Carga e hidrata el JavaScript del componente inmediatamente al cargar la página.

<BuyButton client:load />
  • Prioridad: Media
  • Útil para: Elementos de la UI de menor prioridad que no necesitan ser interactivos inmediatamente.

Carga e hidrata el JavaScript del componente una vez que la página haya terminado con su carga inicial y se haya disparado el evento requestIdleCallback. Si estás en un navegador que no soporta requestIdleCallback, se utilizará el evento load del documento.

<ShowHideButton client:idle />

Añadido en: astro@4.15.0

El tiempo máximo a esperar, en milisegundos, antes de hidratar el componente, incluso si la página aún no ha terminado con su carga inicial.

Esto te permite pasar un valor para la opción timeout de la especificación de requestIdleCallback(). Esto significa que puedes retrasar la hidratación de elementos de la UI de menor prioridad con un mayor control para asegurarte de que tu elemento sea interactivo dentro de un marco de tiempo específico.

<ShowHideButton client:idle={{timeout: 500}} />
  • Prioridad: Baja
  • Útil para: Elementos de la UI de baja prioridad que están muy abajo en la página ("debajo del pliegue") o que consumen tantos recursos al cargarse que preferirías no cargarlos en absoluto si el usuario nunca viera el elemento.

Carga e hidrata el JavaScript del componente una vez que el componente haya entrado en la vista (viewport) del usuario. Esto utiliza un IntersectionObserver internamente para rastrear la visibilidad.

<HeavyImageCarousel client:visible />

Añadido en: astro@4.1.0

Opcionalmente, se puede pasar un valor para rootMargin al IntersectionObserver subyacente. Cuando se especifica rootMargin, el JavaScript del componente se hidratará cuando un margen especificado (en píxeles) alrededor del componente entre en la vista, en lugar del componente en sí.

<HeavyImageCarousel client:visible={{rootMargin: "200px"}} />

Especificar un valor de rootMargin puede reducir los cambios de diseño (CLS), permitir más tiempo para que un componente se hidrate en conexiones de internet más lentas y hacer que los componentes sean interactivos antes, mejorando la estabilidad y la capacidad de respuesta de la página.

  • Prioridad: Baja
  • Útil para: Interruptores de barra lateral u otros elementos que solo podrían ser visibles en ciertos tamaños de pantalla.

client:media={string} carga e hidrata el JavaScript del componente una vez que se cumple una de terminada consulta de medios (media query) de CSS.

<SidebarToggle client:media="(max-width: 50em)" />

client:only={string} omite el renderizado del servidor de HTML y se renderiza solo en el cliente. Actúa de manera similar a client:load en el sentido de que carga, renderiza e hidrata el componente inmediatamente al cargar la página.

¡Debes pasar el framework correcto del componente como valor! Debido a que Astro no ejecuta el componente durante la compilación o en el servidor, Astro no sabe qué framework utiliza tu componente a menos que se lo indiques explícitamente.

<SomeReactComponent client:only="react" />
<SomePreactComponent client:only="preact" />
<SomeSvelteComponent client:only="svelte" />
<SomeVueComponent client:only="vue" />
<SomeSolidComponent client:only="solid-js" />

Para componentes que se renderizan solo en el cliente, también es posible mostrar contenido de respaldo (fallback) mientras se están cargando. Usa slot="fallback" en cualquier elemento hijo para crear contenido que se mostrará solo hasta que tu componente de cliente esté disponible:

<ClientComponent client:only="vue">
<div slot="fallback">Loading</div>
</ClientComponent>

Desde Astro 2.6.0, las integraciones también pueden añadir directivas client:* personalizadas para cambiar cómo y cuándo deben hidratarse los componentes.

Visita la página de la API addClientDirective para obtener más información sobre cómo crear una directiva de cliente personalizada.

Estas directivas controlan cómo se renderizan los componentes de server islands.

La directiva server:defer transforma el componente en una server island, haciendo que se renderice bajo demanda, fuera del alcance del resto del renderizado de la página.

Consulta más información sobre el uso de componentes de server island.
<Avatar server:defer />

Estas directivas solo se pueden usar en etiquetas HTML <script> y <style>, para controlar cómo se manejan tu JavaScript y CSS del lado del cliente en la página.

Por defecto, Astro aplica automáticamente el alcance (scope) de las reglas CSS de <style> al componente. Puedes desactivar este comportamiento con la directiva is:global.

is:global hace que el contenido de una etiqueta <style> se aplique globalmente en la página cuando se incluye el componente. Esto desactiva el sistema de alcance CSS de Astro. Esto es equivalente a envolver todos los selectores dentro de una etiqueta <style> con :global().

Puedes combinar <style> y <style is:global> juntos en el mismo componente, para crear algunas reglas de estilo globales mientras sigues limitando el alcance de la mayoría del CSS de tu componente.

Consulta la página de Estilos y CSS para obtener más detalles sobre cómo funcionan los estilos globales.
<style is:global>
body a { color: red; }
</style>

Por defecto, Astro procesará, optimizará y empaquetará cualquier etiqueta <script> y <style> que vea en la página. Puedes desactivar este comportamiento con la directiva is:inline.

is:inline le indica a Astro que deje la etiqueta <script> o <style> tal como está en el HTML de salida final. El contenido no será procesado, optimizado ni empaquetado. Esto limita algunas características de Astro, como importar un paquete npm o usar un lenguaje que se compila a CSS como Sass.

La directiva is:inline significa que las etiquetas <style> y <script>:

  • No se empaquetarán en un archivo externo. Esto significa que atributos como defer que controlan la carga de un archivo externo no tendrán ningún efecto.
  • No se desduplicará: el elemento aparecerá tantas veces como se renderice.
  • No tendrán sus referencias import/@import/url() resueltas en relación con el archivo .astro.
  • Se renderizará en el HTML de salida final exactamente donde fue escrito.
  • Los estilos serán globales y no tendrán alcance en el componente.
<style is:inline>
/* inline: relative & npm package imports are not supported. */
@import '/assets/some-public-styles.css';
span { color: green; }
</style>
<script is:inline>
/* inline: relative & npm package imports are not supported. */
console.log('I am inlined right here in the final output HTML.');
</script>
Consulta cómo funcionan los scripts del lado del cliente en los componentes de Astro.

define:vars={...} puede pasar variables del lado del servidor desde el frontmatter de tu componente a las etiquetas <script> o <style> del cliente. Se admite cualquier variable de frontmatter serializable en JSON, incluidas las propiedades (props) pasadas a tu componente a través de Astro.props. Los valores se serializan con JSON.stringify().

---
const foregroundColor = "rgb(221 243 228)";
const backgroundColor = "rgb(24 121 78)";
const message = "Astro is awesome!";
---
<style define:vars={{ textColor: foregroundColor, backgroundColor }}>
h1 {
background-color: var(--backgroundColor);
color: var(--textColor);
}
</style>
<script define:vars={{ message }}>
alert(message);
</script>

is:raw indica al compilador de Astro que trate cualquier elemento hijo de ese elemento como texto. Esto significa que se ignorará toda la sintaxis especial de plantillas de Astro dentro de este componente.

Por ejemplo, si tuvieras un componente Katex personalizado que convirtiera algún texto a HTML, podrías hacer que los usuarios hicieran esto:

---
import Katex from '../components/Katex.astro';
---
<Katex is:raw>Some conflicting {syntax} here</Katex>
Contribuir Comunidad Patrocinar