Scripts e Manipulação de Eventos
Você pode adicionar interatividade em seus componentes Astro sem utilizar um framework de UI como React, Svelte, Vue, etc. usando tags <script>
padrões do HTML. Isso te permite enviar JavaScript a ser executado no navegador e adicionar funcionalidade aos seus componentes Astro.
Scripts no lado do Cliente
Scripts podem ser utilizados para adicionar event listeners, enviar dados de analítica, iniciar animações e tudo mais que o JavaScript pode fazer na web.
Por padrão, Astro processará e faz o bundle de tags <script>
, adicionando suporte para a importação de módulos do npm, uso de TypeScript e mais.
Utilizando <script>
no Astro
Em arquivos .astro
, você pode adicionar JavaScript no lado do cliente adicionando uma (ou mais) tags <script>
.
Neste exemplo, adicionar o componente <Ola />
a uma página irá registrar uma mensagem no console do navegador.
Processamento do Script
Por padrão, tags <script>
são processadas pelo Astro.
- Quaisquer importações passaram por bundle, te permitindo importar arquivos locais ou módulos do Node.
- O script processado será injetado no
<head>
da sua página comtype="module"
. - TypeScript é completamente suportado, incluindo a importação de arquivos TypeScript.
- Se o seu componente é usado várias vezes em uma página, o script será adicionado apenas uma vez.
O atributo type="module"
faz com que o navegador trate o script como um módulo JavaScript. Isso traz vários benefícios de desempenho:
- A renderização não é bloqueada. O navegador continua a processar o restante do HTML enquanto o script do módulo e suas dependências são carregados.
- O navegador aguarda o processamento do HTML antes de executar scripts de módulo. Você não precisa escutar o evento “load”.
- Os atributos
async
edefer
são desnecessários. Os scripts de módulo são sempre adiados.
O atributo async
é valioso para scripts normais, pois impede que eles bloqueiem a renderização. No entanto, os scripts de módulo já possuem esse comportamento. Adicionar async
a um script de módulo fará com que ele seja executado antes que a página tenha carregado completamente. Isso provavelmente não é o que você deseja.
Optando por não processar
Para evitar fazer o bundle do script, você pode adicionar a diretiva is:inline
.
Astro não processara suas tags de script em algumas situações. Especialmente, ao adicionar type="module"
ou qualquer outro atributo diferente de src
a uma tag <script>
irá fazer com que o Astro trate a tag como se ela tivesse a diretiva is:inline
. O mesmo será verdade quando o script é escrito em uma expressão JSX.
📚 Veja nossa página de referência de diretivas para mais informações sobre as diretivas disponíveis em tags <script>
.
Incluindo arquivos javascript na sua página
Você pode desejar escrever seus scripts como arquivos .js
/.ts
separados ou precisa referenciar um script externo em outro servidor. Você pode fazer isso os referenciando no atributo src
de uma tag <script>
.
Importando scripts locais
Quando utilizar isto: Se o seu script está dentro de src/
.
Astro irá fazer a build, otimizar e adicionar esses scripts a página para você, seguindo suas regras de processamento de script.
Carregando scripts externos
Quando utilizar isto: Se o seu arquivo JavaScript está dentro de public/
ou em uma CDN.
Para carregar scripts fora do diretório src/
do seu projeto, inclua a diretiva is:inline
. Esta abordagem pula o processamento, bundling e otimizações do JavaScript que são providenciadas pelo Astro quando você importa scripts como descrito acima.
Padrões de script comuns
Manipulando onclick
e outros eventos
Alguns frameworks de UI utilizam uma sintaxe customizada para manipular eventos como onClick={...}
(React/Preact) ou @click="..."
(Vue). Astro segue mais fielmente o HTML padrão e não utiliza uma sintaxe customizada para eventos.
No lugar, você pode utilizar addEventListener
em uma tag <script>
para manipular a interação do usuário.
Se você tem múltiplos componentes <BotaoAlerta />
em uma página, Astro não irá executar o script múltiplas vezes. Scripts passam por bundle e são inclusos apenas uma vez por página. Utilizar querySelectorAll
garante que este script anexe o event listener para cada botão com a classe alerta
encontrado na página.
Web components com elementos customizados
Você pode criar seus próprios elementos HTML com comportamentos customizados usando o padrão Web Components. Definir um elemento customizado em um componente .astro
te permite construir componentes interativos sem precisar de uma biblioteca ou framework de UI.
Neste exemplo, definimos um novo elemento HTML <coracao-astro>
que rastreia quantas vezes você clicou no botão de coração e atualiza a <span>
com o contagem atual.
Há duas vantagens em utilizar um elemento customizado aqui:
-
Ao invés de procurar em toda a página usando
document.querySelector()
, você pode utilizarthis.querySelector()
, que apenas pesquisa dentro da instância do elemento customizado atual. Isso torna mais fácil trabalhar apenas com filhos de uma instância de componente por vez. -
Apesar do
<script>
ser executado apenas uma vez, o navegador irá executar o métodoconstructor()
cada vez que ele encontrar um<coracao-astro>
na página. Isso significa que você pode de forma segura escrever código para um componente por vez, mesmo que você planeje utilizar o componente múltiplas vezes em uma página.
📚 Voc~e pode aprender mais sobre elementos customizados no guia “Reusable Web Components” do web.dev e na introdução da MDN a elementos customizados.
Passando variáveis frontmatter a scripts
Em componentes Astro, o código no frontmatter entre as cercas ---
é executado no servidor e não está disponível no navegador. Para enviar variáveis do servidor para o cliente, nós precisamos de uma forma de armazenar nossas variáveis e então as ler quando o JavaScript é executado no navegador.
Uma forma de fazer isso é utilizando atributos data-*
para armazenar o valor das variáveis no HTML resultante. Scripts, incluindo elementos customizados, podem ler esses atributos utilizando a propriedade dataset
de um elemento assim que o HTML é carregado no navegador.
Neste componente de exemplo, uma prop mensagem
é armazenada no atributo data-mensagem
para que o elemento customizado possa ler this.dataset.mensagem
e obter o valor da prop no navegador.
Agora podemos utilizar nosso componente múltiplas vezes e seremos cumprimentados com uma mensagem diferente para cada uma.
Isto é o que o Astro faz nos bastidores quando você passa props para um componente escrito utilizando um framework de UI como React! Para componentes com uma diretiva client:*
, o Astro cria um elemento customizado <astro-island>
com o atributo props
que armazena as suas props do lado do servidor no HTML resultante.