Saltearse al contenido

Referencia de directivas de maquetado

Las directivas de maquetado son atributos especiales de HTML disponibles dentro del maquetado de los componentes de Astro (archivos .astro), algunas de ellas también pueden usarse en archivos .mdx.

Las directivas de maquetado se utilizan para controlar el comportamiento de un elemento o componente de cierta forma. Una directiva de maquetado puede habilitar alguna característica del compilador que te haga la vida más fácil (como usar class:list en lugar de class). O bien, una directiva puede decirle al compilador de Astro que haga algo especial con ese componente (como hidratar con client:load).

Esta página describe todas las directivas de maquetado disponibles en Astro y cómo funcionan.

Para que una directiva de maquetado sea válida, debes:

  • 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, no todas, pueden tomar un valor personalizado:

  • <X client:load /> (no toma valor)
  • <X class:list={['some-css-class']} /> (toma una matriz)

Una directiva de maquetado nunca se incluye directamente en el HTML del compilado final de un componente.

class:list={...} toma un array de clases y los convierte en un string. Esto está impulsado por la popular biblioteca auxiliar de @lukeed llamada clsx.

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

  • string: Agregado al elemento class
  • Object: Todas las keys verdaderas se agregan al elemento class
  • Array: aplanado
  • false, null, o undefined: Omitido
<!-- Esto -->
<span class:list={[ 'hello goodbye', { world: true }, [ 'friend' ] ]} />
<!-- Se convierte en -->
<span class="hello goodbye world friend"></span>

set:html={string} inyecta un string de HTML en un elemento, similar a la opción el.innerHTML.

¡Astro no verifica automáticamente el valor! Asegúrate que confías en el valor o verificalo manualmente antes de pasarlo al maquetado. Olvidar hacer esto te expondrá a ataques de Cross Site Scripting (XSS).

---
const rawHTMLString = "Hola <strong>Mundo</strong>"
---
<h1>{rawHTMLString}</h1>
<!-- Resultado: <h1>Hola &lt;strong&gt;Mundo&lt;/strong&gt;</h1> -->
<h1 set:html={rawHTMLString} />
<!-- Resultado: <h1>Hola <strong>Mundo</strong></h1> -->

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

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

set:text={string} inyecta un string de texto en un elemento, similar a el.innerText. A diferencia de set:html, Astro verifica automáticamente al valor string que se pasa.

Esto equivale a pasar una variable a una expresión de maquetado de forma directa (por ejemplo: <div>{someText}</div>) y, por lo tanto, esta directiva no se usa comúnmente.

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

De forma predeterminada, un componente de framework no está hidratado en el cliente. Si no se proporciona la directiva client:*, su HTML se representa en la página sin JavaScript.

Una directiva de cliente puede ser usada solamente en un componente de framework UI que sea directamente importado en un componente .astro. Las directivas de hidratación no son compatibles cuando se usan 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 UI de menor prioridad que no necesitan ser interactivos inmediatamente.

Carga e hidrata el componente JavaScript una vez que la página haya terminado con su carga inicial y se haya activado el evento requestIdleCallback. Si está en un navegador que no es compatible con requestIdleCallback, entonces se usará el evento load.

<ShowHideButton client:idle />
  • Prioridad: Baja
  • Útil para: Elementos de la interfaz de usuario de baja prioridad que se encuentran en la parte inferior de la página (“que no son visibles al usuario”) o que requieren tantos recursos para cargar que preferiría no cargarlos en absoluto si el usuario nunca vio el elemento.

Carga e hidrata el JavaScript del componente una vez que haya ingresado al viewport del usuario. Esto utiliza un IntersectionObserver internamente para realizar un seguimiento de la visibilidad.

<HeavyImageCarousel client:visible />

Agregado en: astro@4.1.0 Nuevo

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

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

Especificar un valor de rootMargin puede reducir los desplazamientos de diseño (CLS), permitir más tiempo para que un componente se hidrate en conexiones a 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: Alternar las barras de navegación u otros elementos que solo deben mostrarse en ciertos tamaños de pantalla.

client:media={string} carga e hidrata el componente JavaScript una vez que se cumple una determinada media query de CSS.

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

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

¡Debes pasar el framework correcto al componente! Debido a que Astro no ejecuta el componente durante su compilación/en el servidor, Astro no sabe qué framework usa el 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" />

Directivas de cliente personalizadas

Sección titulada Directivas de cliente personalizadas

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

Consulta la API addClientDirective para saber más sobre cómo crear una directiva de cliente personalizada.

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

De forma predeterminada, Astro aplica automáticamente las reglas CSS <style> localmente al componente. Puedes optar por no participar con 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 el componente es incluido. Esto deshabilita el alcance local de 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 mantienes la mayor parte del CSS con un alcance local dentro del componente de Astro.

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

De forma predeterminada, Astro procesará, optimizará y empaquetará cualquier etiqueta <script> y <style> que vea en la página. Puedes optar por evitar 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 final. Los contenidos no serán procesados, optimizados o agrupados. Esto limita algunas características de Astro, como importar un paquete npm o usar un lenguaje de compilación a CSS como Sass.

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

  • No se empaquetarán como un archivo externo. Esto significa que atributos tales como defer que controlan la carga de archivos externos, no tendrán efecto.
  • No se deduplicarán: el elemento aparecerá tantas veces como se represente.
  • No se resolverán sus referencias import/@import/url() en relación con el archivo .astro.
  • Se renderizarán en el HTML final exactamente donde se crearon.
  • Los estilos serán globales y no tendrán alcance local en el componente.
<style is:inline>
/* inline: Las importaciones de paquetes relativos y npm no son compatibles. */
@import '/assets/some-public-styles.css';
span { color: green; }
</style>
<script is:inline>
/* inline: Las importaciones de paquetes relativos y npm no son compatibles. */
console.log('Estoy inline aquí en el HTML generado.');
</script>
Mira cómo funcionan los scripts del lado del cliente en los componentes de Astro.

define:vars={...} pueden pasar variables del servidor desde el frontmatter del componente a las etiquetas <script> o <style> del cliente. Cualquier variable de frontmatter JSON-serializable es compatible, incluyendo las props pasadas al componente a través de Astro.props. Los valores son serializados por medio de JSON.stringify()

---
const foregroundColor = "rgb(221 243 228)";
const backgroundColor = "rgb(24 121 78)";
const message = "¡Astro es espectacular!";
---
<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 a cualquier elemento hijo de ese componente como texto. Esto significa que toda la sintaxis especial de maquetado de Astro se ignorará dentro de este componente.

Usado internamente por el componente <Markdown />.

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

---
import Katex from '../components/Katex.astro';
---
<Katex is:raw>Algunas {sintaxis} conflictivas aquí</Katex>