Referencia de expresiones de plantilla
La sintaxis de los componentes Astro es un superconjunto de HTML. Se diseñó para que resultara familiar a cualquier persona con experiencia escribiendo HTML o JSX, y añade compatibilidad para incluir componentes y expresiones de JavaScript.
Expresiones similares a JSX
Sección titulada «Expresiones similares a JSX»Puedes definir variables JavaScript locales dentro del script del componente frontmatter entre las dos separadores de código (---) de un componente Astro. A continuación, puedes inyectar estas variables en la plantilla HTML del componente usando expresiones similares a JSX.
Con este enfoque, puedes incluir valores dinámicos que se calculan en el frontmatter. Pero una vez incluidos, estos valores no son reactivos y nunca cambiarán. Los componentes Astro son plantillas que sólo se ejecutan una vez, durante el paso de renderizado.
Mira a continuación más ejemplos de diferencias entre Astro y JSX.
Variables
Sección titulada «Variables»Las variables locales pueden añadirse al HTML usando la sintaxis de llaves:
---const nombre = 'Astro';---<div> <h1>¡Hola {nombre}!</h1> <!-- Sale como <h1>¡Hola Astro!</h1> --></div>Atributos dinámicos
Sección titulada «Atributos dinámicos»Las variables locales pueden usarse entre llaves para pasar valores de atributos tanto a elementos HTML como a componentes:
---import MyComponent from './MyComponent.astro';const nombre = 'Astro';---<h1 class={nombre}>Se admiten expresiones de atributos</h1>
<MyComponent templateLiteralNameAttribute={`MiNombreEs${nombre}`} />Los atributos HTML se convertirán en cadenas de texto, por lo que no es posible pasar funciones y objetos a elementos HTML. Por ejemplo, no se puede asignar un controlador de eventos a un elemento HTML en un componente de Astro:
---function handleClick () { console.log('¡botón pulsado!');}---<!-- ❌ ¡Esto no funciona! ❌ --><button onClick={handleClick}>¡No pasará nada cuando me hagas clic!</button>En su lugar, usa un script del lado del cliente para agregar el controlador de eventos, como lo harías en JavaScript convencional:
------<button id="button">Púlsame</button><script> function handleClick () { console.log('¡botón pulsado!'); } document.getElementById("button")?.addEventListener("click", handleClick);</script>HTML Dinamico
Sección titulada «HTML Dinamico»Las variables locales pueden usarse en funciones similares a JSX para producir elementos HTML generados dinámicamente:
---const items = ['Perro', 'Gato', 'Ornitorrinco'];---<ul> {items.map((item) => ( <li>{item}</li> ))}</ul>Astro puede mostrar HTML condicionalmente usando operadores lógicos JSX y expresiones ternarias.
---const visible = true;---{visible && <p>¡Muéstramelo!</p>}
{visible ? <p>¡Muéstramelo!</p> : <p>¡Si no, muéstramelo!</p>}Etiquetas dinámicas
Sección titulada «Etiquetas dinámicas»También puedes usar etiquetas dinámicas asignando un nombre de etiqueta HTML a una variable o reasignando la importación de un componente:
---import MyComponent from './MyComponent.astro';const Element = 'div'const Component = MyComponent;---<Element>¡Hola!</Element> <!-- se representa como <div>¡Hola!</div> --><Component /> <!-- se representa como <MyComponent /> -->Al usar etiquetas dinámicas:
-
Los nombres de las variables deben ir en mayúsculas. Por ejemplo, usa
Elemento, noelemento. De lo contrario, Astro intentará representar el nombre de la variable como una etiqueta HTML literal. -
No se admiten directivas de hidratación. Cuando se usan las directivas
client:*de hidratación (EN), Astro necesita saber qué componentes empaquetar para producción, y el patrón de etiquetas dinámicas impide que esto funcione. -
La directiva define:vars no está soportada. Si no puedes envolver los hijos con un elemento adicional (por ejemplo,
<div>), entonces puedes añadir manualmente unstyle={`--myVar:${value}`}a tu Elemento.
Fragmentos
Sección titulada «Fragmentos»Astro soporta la notación <> </> y también ofrece un componente integrado <Fragment />. Este componente puede resultar útil para evitar elementos de envoltura al añadir directivas set:* para insertar una cadena de texto HTML.
En el siguiente ejemplo se renderiza el texto de un párrafo usando el componente <Fragment />:
---const htmlString = '<p>Contenido HTML sin procesar</p>';---<Fragment set:html={htmlString} />Diferencias entre Astro y JSX
Sección titulada «Diferencias entre Astro y JSX»La sintaxis de los componentes de Astro es un superconjunto de HTML. Se ha diseñado para que resulte familiar a cualquier persona con experiencia en HTML o JSX, pero hay un par de diferencias clave entre los archivos .astro y JSX.
Atributos
Sección titulada «Atributos»En Astro, se puede usar el formato estándar kebab-case para todos los atributos HTML en lugar del camelCase usado en JSX. Esto funciona incluso para class, que no está soportado por React.
<div className="box" dataValue="3" /><div class="box" data-value="3" />Elementos múltiples
Sección titulada «Elementos múltiples»Una plantilla de componente en Astro puede renderizar múltiples elementos sin necesidad de envolver todo en un solo <div> o <>, a diferencia de JavaScript o JSX.
---// Una plantilla con múltiples elementos---<p>No es necesario envolver los elementos en un único elemento contenedor.</p><p>Astro admite múltiples elementos raíz en una plantilla.</p>Comentarios
Sección titulada «Comentarios»En Astro, puedes utilizar comentarios HTML estándar o comentarios de estilo JavaScript.
------<!-- La sintaxis de los comentarios HTML es válida en los archivos .astro -->{/* La sintaxis de los comentarios JS también es válida */}Los comentarios HTML se incluirán en el DOM del navegador, mientras que los JS se omitirán. Para dejar mensajes TODO u otras explicaciones exclusivas de desarrollo, es posible que desees utilizar comentarios de estilo JavaScript en su lugar.
Utilidades de componentes
Sección titulada «Utilidades de componentes»Astro.slots
Sección titulada «Astro.slots»Astro.slots contiene funciones de utilidad para modificar los elementos hijo ubicados en slots de un componente Astro.
Astro.slots.has()
Sección titulada «Astro.slots.has()»Tipo: (slotName: string) => boolean
Puedes comprobar si existe contenido para un nombre de slot concreto con Astro.slots.has(). Esto puede resultar útil cuando quieras envolver el contenido de un slot, pero solo quieres renderizar los elementos de envoltura cuando se esté usando dicho slot.
------<slot />
{Astro.slots.has('more') && ( <aside> <h2>Más</h2> <slot name="more" /> </aside>)}Astro.slots.render()
Sección titulada «Astro.slots.render()»Tipo: (slotName: string, args?: any[]) => Promise<string>
Puedes renderizar de forma asíncrona el contenido de un slot en una cadena de texto HTML utilizando Astro.slots.render().
---const html = await Astro.slots.render('default');---<Fragment set:html={html} />¡Esto es para casos de uso avanzados! En la mayoría de los casos, es más sencillo mostrar el contenido de un slot con el elemento <slot />.
Astro.slots.render() admite, de forma opcional, un segundo argumento: una lista de parámetros que se pasarán a cualquier función hija. Esto puede resultar útil para componentes de utilidad personalizados.
Por ejemplo, este componente <Shout /> convierte su propiedad message a mayúsculas y la pasa al slot predeterminado:
---const message = Astro.props.message.toUpperCase();let html = '';if (Astro.slots.has('default')) { html = await Astro.slots.render('default', [message]);}---<Fragment set:html={html} />Una función callback pasada como elemento hijo de <Shout /> recibirá el parámetro message en mayúsculas:
---import Shout from '../components/Shout.astro';---<Shout message="¡ranuras!"> {(message: string) => <div>{message}</div>}</Shout>
<!-- Se renderiza como <div>¡RANURAS!</div> -->Las funciones callback se pueden pasar a slots con nombre dentro de una etiqueta de elemento HTML de envoltura mediante el atributo slot. Este elemento solo se utiliza para transferir la función callback a un slot con nombre y no se mostrará en la página.
<Shout message="¡ranuras!"> <fragment slot="message"> {(message: string) => <div>{message}</div>} </fragment></Shout>Usa un elemento HTML estándar como etiqueta contenedora o cualquier etiqueta en minúsculas (p. ej., <fragment> en lugar de <Fragment />) que no se interprete como un componente. No uses el elemento HTML <slot>, ya que se interpretará como un slot de Astro.
Astro.self
Sección titulada «Astro.self»Astro.self permite llamar a los componentes Astro de forma recursiva. Este comportamiento te permite renderizar un componente Astro desde su propio interior usando <Astro.self> en la plantilla del componente. Esto puede resultar útil para iterar sobre grandes almacenes de datos y estructuras de datos anidadas.
---type Props = { items: (string | string[])[];};const { items } = Astro.props;---
<ul class="lista-anidada"> { items.map((item) => ( <li> {/* Si hay una estructura de datos anidada, mostramos `<Astro.self>` */} {/* y se pueden pasar propiedades mediante la llamada recursiva */} {Array.isArray(item) ? <Astro.self items={item} /> : item} </li> )) }</ul>Este componente se podría usar así:
---import NestedList from './NestedList.astro';---<NestedList items={['A', ['B', 'C'], 'D']} />Y se rendezaría en HTML así:
<ul class="lista-anidada"> <li>A</li> <li> <ul class="lista-anidada"> <li>B</li> <li>C</li> </ul> </li> <li>D</li></ul>