Scripts and event handling
यह कंटेंट अभी तक आपकी भाषा में उपलब्ध नहीं है।
You can send JavaScript to the browser and add functionality to your Astro components using <script>
tags in the component template.
Scripts add interactivity to your site, such as handling events or updating content dynamically, without the need for a UI framework like React, Svelte, or Vue. This avoids the overhead of shipping framework JavaScript and doesn’t require you to know any additional framework to create a full-featured website or application.
Client-Side Scripts
Section titled “Client-Side Scripts”Scripts can be used to add event listeners, send analytics data, play animations, and everything else JavaScript can do on the web.
Astro automatically enhances the HTML standard <script>
tag with bundling, TypeScript, and more. See how astro processes scripts for more details.
<button data-confetti-button>Celebrate!</button>
<script> // Import from npm package. import confetti from 'canvas-confetti';
// Find our component DOM on the page. const buttons = document.querySelectorAll('[data-confetti-button]');
// Add event listeners to fire confetti when a button is clicked. buttons.forEach((button) => { button.addEventListener('click', () => confetti()); });</script>
Script processing
Section titled “Script processing”By default, Astro processes <script>
tags that contain no attributes (other than src
) in the following ways:
- TypeScript support: All scripts are TypeScript by default.
- Import bundling: Import local files or npm modules, which will be bundled together.
- Type Module: Processed scripts become
type="module"
automatically. - Deduplication: If a component that contains a
<script>
is used multiple times on a page, the script will only be included once. - Automatic inlining: If the script is small enough, Astro will inline it directly into the HTML to reduce the number of requests.
<script> // Processed! Bundled! TypeScript! // Importing local scripts and from npm packages works.</script>
Unprocessed scripts
Section titled “Unprocessed scripts”Astro will not process a <script>
tag if it has any attribute other than src
.
You can add the is:inline
directive to intentionally opt out of processing for a script.
<script is:inline> // Will be rendered into the HTML exactly as written! // Not transformed: no TypeScript and no import resolution by Astro. // If used inside a component, this code is duplicated for each instance.</script>
Include JavaScript files on your page
Section titled “Include JavaScript files on your page”You may want to write your scripts as separate .js
/.ts
files or need to reference an external script on another server. You can do this by referencing these in a <script>
tag’s src
attribute.
Import local scripts
Section titled “Import local scripts”When to use this: when your script lives inside of src/
.
Astro will process these scripts according to the script processing rules.
<!-- relative path to script at `src/scripts/local.js` --><script src="../scripts/local.js"></script>
<!-- also works for local TypeScript files --><script src="./script-with-types.ts"></script>
Load external scripts
Section titled “Load external scripts”When to use this: when your JavaScript file lives inside of public/
or on a CDN.
To load scripts outside of your project’s src/
folder, include the is:inline
directive. This approach skips the JavaScript processing, bundling, and optimizations that are provided by Astro when you import scripts as described above.
<!-- absolute path to a script at `public/my-script.js` --><script is:inline src="/my-script.js"></script>
<!-- full URL to a script on a remote server --><script is:inline src="https://my-analytics.com/script.js"></script>
Common script patterns
Section titled “Common script patterns”Handle onclick
and other events
Section titled “Handle onclick and other events”Some UI frameworks use custom syntax for event handling like onClick={...}
(React/Preact) or @click="..."
(Vue). Astro follows standard HTML more closely and does not use custom syntax for events.
Instead, you can use addEventListener
in a <script>
tag to handle user interactions.
<button class="alert">Click me!</button>
<script> // Find all buttons with the `alert` class on the page. const buttons = document.querySelectorAll('button.alert');
// Handle clicks on each button. buttons.forEach((button) => { button.addEventListener('click', () => { alert('Button was clicked!'); }); });</script>
If you have multiple <AlertButton />
components on a page, Astro will not run the script multiple times. Scripts are bundled and only included once per page. Using querySelectorAll
ensures that this script attaches the event listener to every button with the alert
class found on the page.
Web components with custom elements
Section titled “Web components with custom elements”You can create your own HTML elements with custom behavior using the Web Components standard. Defining a custom element in a .astro
component allows you to build interactive components without needing a UI framework library.
In this example, we define a new <astro-heart>
HTML element that tracks how many times you click the heart button and updates the <span>
with the latest count.
<!-- Wrap the component elements in our custom element “astro-heart”. --><astro-heart> <button aria-label="Heart">💜</button> × <span>0</span></astro-heart>
<script> // Define the behaviour for our new type of HTML element. class AstroHeart extends HTMLElement { connectedCallback() { let count = 0;
const heartButton = this.querySelector('button'); const countSpan = this.querySelector('span');
// Each time the button is clicked, update the count. heartButton.addEventListener('click', () => { count++; countSpan.textContent = count.toString(); }); } }
// Tell the browser to use our AstroHeart class for <astro-heart> elements. customElements.define('astro-heart', AstroHeart);</script>
There are two advantages to using a custom element here:
-
Instead of searching the whole page using
document.querySelector()
, you can usethis.querySelector()
, which only searches within the current custom element instance. This makes it easier to work with only the children of one component instance at a time. -
Although a
<script>
only runs once, the browser will run our custom element’sconnectedCallback()
method each time it finds<astro-heart>
on the page. This means you can safely write code for one component at a time, even if you intend to use this component multiple times on a page.
Pass frontmatter variables to scripts
Section titled “Pass frontmatter variables to scripts”In Astro components, the code in the frontmatter (between the ---
fences) runs on the server and is not available in the browser.
To pass server-side variables to client-side scripts, store them in data-*
attributes on HTML elements. Scripts can then access these values using the dataset
property.
In this example component, a message
prop is stored in a data-message
attribute, so the custom element can read this.dataset.message
and get the value of the prop in the browser.
---const { message = 'Welcome, world!' } = Astro.props;---
<!-- Store the message prop as a data attribute. --><astro-greet data-message={message}> <button>Say hi!</button></astro-greet>
<script> class AstroGreet extends HTMLElement { connectedCallback() { // Read the message from the data attribute. const message = this.dataset.message; const button = this.querySelector('button'); button.addEventListener('click', () => { alert(message); }); } }
customElements.define('astro-greet', AstroGreet);</script>
Now we can use our component multiple times and be greeted by a different message for each one.
---import AstroGreet from '../components/AstroGreet.astro';---
<!-- Use the default message: “Welcome, world!” --><AstroGreet />
<!-- Use custom messages passed as a props. --><AstroGreet message="Lovely day to build components!" /><AstroGreet message="Glad you made it! 👋" />
This is actually what Astro does behind the scenes when you pass props to a component written using a UI framework like React! For components with a client:*
directive, Astro creates an <astro-island>
custom element with a props
attribute that stores your server-side props in the HTML output.
Combining scripts and UI Frameworks
Section titled “Combining scripts and UI Frameworks”Elements rendered by a UI framework may not be available yet when a <script>
tag executes. If your script also needs to handle UI framework components, using a custom element is recommended.