Saltar al contenido

Referencia de expresiones de plantilla

La sintaxis de componentes de Astro es un superconjunto de HTML. La sintaxis fue diseñada para sentirse familiar para cualquiera con experiencia escribiendo HTML o JSX, y añade soporte para incluir componentes y expresiones JavaScript.

Puedes definir variables JavaScript locales dentro del script del frontmatter del componente entre las dos vallas de código (---) de un componente de Astro. Luego puedes inyectar estas variables en la plantilla HTML del componente usando expresiones tipo JSX!

Las variables locales pueden añadirse al HTML usando la sintaxis de llaves:

src/components/Variables.astro
---
const name = "Astro";
---
<div>
<h1>Hello {name}!</h1> <!-- Outputs <h1>Hello Astro!</h1> -->
</div>

Las variables locales pueden usarse entre llaves para pasar valores de atributos tanto a elementos HTML como a componentes:

src/components/DynamicAttributes.astro
---
const name = "Astro";
---
<h1 class={name}>Attribute expressions are supported</h1>
<MyComponent templateLiteralNameAttribute={`MyNameIs${name}`} />

Las variables locales pueden usarse en funciones tipo JSX para producir elementos HTML generados dinámicamente:

src/components/DynamicHtml.astro
---
const items = ["Dog", "Cat", "Platypus"];
---
<ul>
{items.map((item) => (
<li>{item}</li>
))}
</ul>

Astro puede mostrar HTML condicionalmente usando operadores lógicos JSX y expresiones ternarias.

src/components/ConditionalHtml.astro
---
const visible = true;
---
{visible && <p>Show me!</p>}
{visible ? <p>Show me!</p> : <p>Else show me!</p>}

También puedes usar tags dinámicos asignando un nombre de etiqueta HTML a una variable o con una reasignación de import de componente:

src/components/DynamicTags.astro
---
import MyComponent from "./MyComponent.astro";
const Element = 'div'
const Component = MyComponent;
---
<Element>Hello!</Element> <!-- renders as <div>Hello!</div> -->
<Component /> <!-- renders as <MyComponent /> -->

Al usar tags dinámicos:

  • Los nombres de variables deben ir en mayúscula. Por ejemplo, usa Element, no element. De lo contrario, Astro intentará renderizar el nombre de tu variable como una etiqueta HTML literal.

  • Las directivas de hidratación no son soportadas. Al usar directivas de hidratación client:*, Astro necesita saber qué componentes empaquetar para producción, y el patrón de tag dinámico impide que esto funcione.

  • La directiva define:vars no es soportada. Si no puedes envolver los hijos con un elemento extra (ej. <div>), entonces puedes añadir manualmente un style={`--myVar:${value}`} a tu Element.

Astro soporta la notación <> </> y también proporciona un componente integrado <Fragment />. Este componente puede ser útil para evitar elementos contenedores al añadir directivas set:* para inyectar un string HTML.

El siguiente ejemplo renderiza texto de párrafo usando el componente <Fragment />:

src/components/SetHtml.astro
---
const htmlString = '<p>Raw HTML content</p>';
---
<Fragment set:html={htmlString} />

La sintaxis de componentes de Astro es un superconjunto de HTML. Fue diseñada para sentirse familiar para cualquiera con experiencia en HTML o JSX, pero hay un par de diferencias clave entre los archivos .astro y JSX.

En Astro, usas el formato estándar kebab-case para todos los atributos HTML en lugar del camelCase usado en JSX. Esto incluso funciona para class, que no es soportado por React.

example.astro
<div className="box" dataValue="3" />
<div class="box" data-value="3" />

Una plantilla de componente de Astro puede renderizar múltiples elementos sin necesidad de envolver todo en un único <div> o <>, a diferencia de JavaScript o JSX.

src/components/RootElements.astro
---
// Template with multiple elements
---
<p>No need to wrap elements in a single containing element.</p>
<p>Astro supports multiple root elements in a template.</p>

En Astro, puedes usar comentarios HTML estándar o comentarios estilo JavaScript.

example.astro
---
---
<!-- HTML comment syntax is valid in .astro files -->
{/* JS comment syntax is also valid */}

Astro.slots contiene funciones utilitarias para modificar los hijos slotted de un componente de Astro.

Type: (slotName: string) => boolean

Puedes verificar si existe contenido para un nombre de slot específico con Astro.slots.has(). Esto puede ser útil cuando quieres envolver contenidos de slot pero solo quieres renderizar los elementos contenedores cuando el slot está siendo usado.

src/pages/index.astro
---
---
<slot />
{Astro.slots.has('more') && (
<aside>
<h2>More</h2>
<slot name="more" />
</aside>
)}

Type: (slotName: string, args?: any[]) => Promise<string>

Puedes renderizar asincrónicamente el contenido de un slot a un string de HTML usando Astro.slots.render().

---
const html = await Astro.slots.render('default');
---
<Fragment set:html={html} />

Astro.slots.render() acepta opcionalmente un segundo argumento: un array de parámetros que se reenviarán a cualquier función hija. Esto puede ser útil para componentes utilitarios personalizados.

Por ejemplo, este componente <Shout /> convierte su prop message a mayúsculas y la pasa al slot por defecto:

src/components/Shout.astro
---
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 hija de <Shout /> recibirá el parámetro message en mayúsculas:

src/pages/index.astro
---
import Shout from "../components/Shout.astro";
---
<Shout message="slots!">
{(message) => <div>{message}</div>}
</Shout>
<!-- renders as <div>SLOTS!</div> -->

Las funciones callback pueden pasarse a slots nombrados dentro de una etiqueta de elemento HTML contenedor con un atributo slot. Este elemento solo se usa para transferir el callback a un slot nombrado y no se renderizará en la página.

<Shout message="slots!">
<fragment slot="message">
{(message) => <div>{message}</div>}
</fragment>
</Shout>

Usa un elemento HTML estándar para la etiqueta contenedora o cualquier etiqueta en minúsculas (ej. <fragment> en lugar de <Fragment />) que no será interpretada como un componente. No uses el elemento HTML <slot> ya que será interpretado como un slot de Astro.

Astro.self permite que los componentes de Astro sean llamados recursivamente. Este comportamiento te permite renderizar un componente de Astro desde dentro de sí mismo usando <Astro.self> en la plantilla del componente. Esto puede ayudar a iterar sobre grandes almacenes de datos y estructuras de datos anidadas.

NestedList.astro
---
const { items } = Astro.props;
---
<ul class="nested-list">
{items.map((item) => (
<li>
<!-- If there is a nested data-structure we render `<Astro.self>` -->
<!-- and can pass props through with the recursive call -->
{Array.isArray(item) ? (
<Astro.self items={item} />
) : (
item
)}
</li>
))}
</ul>

Este componente podría entonces usarse así:

---
import NestedList from './NestedList.astro';
---
<NestedList items={['A', ['B', 'C'], 'D']} />

Y renderizaría HTML así:

<ul class="nested-list">
<li>A</li>
<li>
<ul class="nested-list">
<li>B</li>
<li>C</li>
</ul>
</li>
<li>D</li>
</ul>
Contribuir Comunidad Patrocinar