Pular para o conteúdo

Referência de Diretivas de Template

Diretivas de template são um tipo especial de atributo HTML disponível dentro do template de qualquer componente Astro (arquivos .astro), com alguns podendo ser utilizados em arquivos .mdx.

Diretivas de template são utilizadas para controlar o comportamento de um elemento ou componente de alguma forma. Uma diretiva de template pode habilitar alguma funcionalidade do compilador que facilitaria sua vida (como utilizar class:list ao invés de class). Ou então, uma diretiva pode dizer para o compilador do Astro fazer algo especial com aquele componente (como hidratá-lo com client:load).

Esta página descreve todas as diretivas de template disponíveis para você no Astro e como elas funcionam.

Para uma diretiva de template ser válida, ela deve:

  • Incluir um dois-pontos : em seu nome, utilizando o padrão X:Y (ex: client:load).
  • Ser visível ao compilador (ex.:X {...atributo} não funcionaria se atributo contivesse uma diretiva).

Algumas diretivas de template, mas não todas, podem receber um valor customizado:

  • <X client:load /> (recebe nenhum valor)
  • <X class:list={['alguma-classe-css']} /> (recebe um array)

Uma diretiva de template nunca é inclusa diretamente no HTML final resultante de um componente.

class:list={...} recebe um array de valores de classes e as converte em uma string de classes. Isso é fornecido pela famosa biblioteca utilitária clsx feita por @lukeed.

class:list recebe um array de vários diferentes tipos de valores:

  • string: Adicionadas ao elemento class
  • Object: Todas as chaves com valor truthy são adicionadas ao elemento class
  • Array: Inserido como uma string dos valores
  • Set: Inserido como uma string dos valores
  • false, null ou undefined: pulado
<!-- Isso -->
<span class:list={[ 'ola tchau', { mundo: true }, [ 'amigo' ] ]} />
<!-- Se torna -->
<span class="olá tchau mundo amigo"></span>

set:html={string} injeta uma string HTML em um elemento, similar a se utilizar el.innerHTML.

O valor não é automaticamente sanitizado pelo Astro! Tenha certeza de que o valor inserido é seguro, ou que você o sanitizou manualmente antes de passá-lo ao template. Esquecer disto vai te deixar exposto a ataques de Cross Site Scripting.

---
const stringHtmlBruta = "Olá <strong>Mundo</strong>"
---
<h1>{stringHtmlBruta}</h1>
<!-- Resultado final: <h1>Olá &lt;strong&gt;Mundo&lt;/strong&gt;</h1> -->
<h1 set:html={stringHtmlBruta} />
<!-- Resultado final: <h1>Olá <strong>Mundo</strong></h1> -->

Você também pode utilizar set:html em um <Fragment> para evitar adicionar um elemento wrapper desnecessário. Isso pode ser especialmente útil ao se buscar HTML de um CMS.

---
const conteudoCMS = await buscarHtmlCMS();
---
<Fragment set:html={conteudoCMS}>

set:html={Promise<string>} injeta uma string HTML em um elemento que é envolvido em uma Promise.

Isso pode ser usado para injetar HTML armazenado externamente, como de um banco de dados.

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

set:html={Promise<Response>} injeta uma Response em um elemento.

Isso é mais útil quando estiver utilizando fetch(). Por exemplo, ao buscar postagens antigas de um gerador de sites estáticos anterior.

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

set:html pode ser utilizado em qualquer tag e não tem que incluir HTML. Por exemplo, utilize com JSON.stringify() em uma tag <script> para adicionar um esquema JSON-LD em sua página.

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

set:text={string} injeta uma string de texto em um elemento, similar a se utilizar el.innerText. Diferente de set:html, o valor string que é passado é automaticamente sanitizado pelo Astro.

Isso é equivalente a apenas passar uma variável em uma expressão de template diretamente (ex: <div>{algumTexto}</div>) e por isso, essa diretiva não é comumente utilizada.

Estas diretivas controlam como componentes de Frameworks de UI são hidratados na página.

Por padrão, um componente de framework de UI não é hidratado no cliente, se nenhuma diretiva client:* é providenciada, seu HTML é renderizado na página sem nenhum JavaScript.

Uma diretiva de cliente pode ser usada apenas em um componente de framework de UI que é diretamente importado em um componente .astro. Diretivas de hidratação não são suportadas ao utilizar tags dinâmicas e componentes customizados passados pela prop components.

  • Prioridade: Alta
  • Útil para: Elementos de UI imediatamente visíveis que precisam ser interativos o mais rápido possível.

Carrega e hidrata o JavaScript do componente imediatamente ao carregar a página.

<BotaoComprar client:load />
  • Prioridade: Média
  • Útil para: Elementos de UI de baixa prioridade, que não precisam ser imediatamente interativos.

Carrega e hidrata o JavaScript do componente assim que a página termina seu carregamento inicial e o evento requestIdleCallback é disparado. Se você estiver em um navegador que não suporta requestIdleCallback, então o evento load é utilizado.

<BotaoMostraEEsconde client:idle />
  • Prioridade: Baixa
  • Útil para: Elementos de UI de baixa prioridade que ou estão mais para baixo (“fora da tela”) ou que consomem muitos recursos e que você prefere que não sejam carregados a não ser que o usuário veja o elemento.

Carrega e hidrata o JavaScript do componente uma vez que o componente entrou na janela de exibição do usuário. Isto utiliza IntersectionObserver internamente para observar a visibilidade.

<CarrosselDeImagensPesado client:visible />
  • Prioridade: Baixa
  • Útil para: Toggles de barras laterais ou outros elementos que podem ser visíveis apenas em certos tamanhos de tela.

client:media={string} carrega e hidrata o JavaScript do componente assim que uma certa media query de CSS é atingida.

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

client:only={string} pula renderização de HTML no servidor e renderiza apenas no cliente. É similar a client:load no sentido em que ele carrega, renderiza e hidrata o componente imediatamente na página.

Você deve passar o framework correto do componente como valor! Pois como o Astro não executa o componente durante a build / no servidor, Astro não sabe que framework seu componente utiliza a não ser que você o diga explicitamente.

<AlgumComponenteReact client:only="react" />
<AlgumComponentePreact client:only="preact" />
<AlgumComponenteSvelte client:only="svelte" />
<AlgumComponenteVue client:only="vue" />
<AlgumComponenteSolid client:only="solid-js" />

Desde o Astro 2.6.0, integrações também podem adicionar diretivas client:* customizadas para alterar como e quando os componentes devem ser hidratados.

Visite a página da API addClientDirective para aprender mais sobre como criar uma diretiva de cliente customizada.

Estas diretivas só podem ser utilizadas nas tags <script> e <style> do HTML, para controlar como o seu JavaScript e CSS no lado do cliente são utilizados pela página.

Por padrão, Astro automaticamente escopa as regras de CSS de <style> ao componente. Você pode remover esse comportamento com a diretiva is:global.

is:global faz com que o conteúdo de uma tag <style> seja aplicado globalmente na página quando o componente está incluso. Isso desabilita o sistema de escopo de CSS do Astro. É o equivalente a envolver todos os seus seletores numa tag <style> com :global().

Você pode combinar <style> e <style is:global> no mesmo componente, para criar algumas regras de estilo globais enquanto ainda escopa a maioria do CSS do seu componente.

📚 Veja a página Estilização e CSS para mais detalhas em como estilos globais funcionam.

<style is:global>
body a { color: red; }
</style>

Por padrão, Astro irá processar, otimizar e fazer o bundle de tags <script> e <style> que ele ver na página. Você pode remover esse comportamento com a diretiva is:inline.

is:inline diz ao Astro para deixar a tag <script> ou <style> como se fosse o HTML final resultante. Seus conteúdos não serão processados, otimizados ou passarão por bundle. Isso limita algumas funcionalidades do Astro, como importar pacotes npm ou utilizar uma linguagem que compila para CSS como Sass.

A diretiva is:inline significa que tags <style> ou <script>:

  • Não passarão por bundle em um arquivo externo. Isso significa que atributos como defer que controlam o carregamento de um arquivo externo não terão efeito.
  • Tags duplicadas não serão removidas - o elemento irá aparecer quantas vezes ele for renderizado.
  • Não terá suas referências de import/@import/url() resolvidas relativamente ao arquivo .astro.
  • Serão renderizadas no HTML final resultante exatamente como foram escritas.
  • Estilos serão globais e não com escopo exclusivo ao componente.
<style is:inline>
/* inline: importações relativas e de pacotes npm não são suportadas. */
@import '/assets/algum-css-publico.css';
span { color: green; }
</style>
<script is:inline>
/* inline: importações relativas e de pacotes npm não são suportadas. */
console.log('Eu sou assim tanto aqui quanto no HTML final resultante.');
</script>

📚 Veja como scripts no lado do cliente funcionam em componentes Astro.

define:vars={...} pode passar variáveis do frontmatter do seu componente no lado do servidor para tags <script> ou <style> do cliente. Qualquer variável frontmatter serializável como JSON é suportada, incluindo props passadas ao seu componente através de Astro.props. Valores são serializados com JSON.stringify().

---
const corPrimeiroPlano = "rgb(221 243 228)";
const corPlanoDeFundo = "rgb(24 121 78)";
const mensagem = "Astro é incrível!";
---
<style define:vars={{ corTexto: corPrimeiroPlano, corPlanoDeFundo }}>
h1 {
background-color: var(--corPlanoDeFundo);
color: var(--corTexto);
}
</style>
<script define:vars={{ mensagem }}>
alert(mensagem);
</script>

is:raw instrui o compilador do Astro a tratar qualquer elemento-filho do elemento como texto. Isso significa que toda a sintaxe de template especial do Astro será ignorada dentro desse componente.

Por exemplo, se você tivesse um componente Katex customizado que converte algum texto para HTML, usuários poderiam fazer isso:

---
import Katex from '../components/Katex.astro';
---
<Katex is:raw>Alguma {sintaxe} conflitante aqui</Katex>