#How to use a variable in `<script>` section
8 messages · Page 1 of 1 (latest)
To use a variable defined in the frontmatter (the code fence section at the top of your .astro file) inside a <script> tag (which runs in the browser), you need to explicitly pass the variable from the server-side context to the client-side script. There are two main approaches in Astro:
1. Using data-* Attributes
Store the variable in a data-* attribute on an HTML element, then access it in your script using the dataset property. For example:
---
// Frontmatter: server-side
const message = "Hello from frontmatter!";
---
<!-- Pass the variable to the DOM -->
<button data-message={message}>Click me</button>
<script>
const button = document.querySelector('button[data-message]');
const message = button.dataset.message;
button.addEventListener('click', () => {
alert(message);
});
</script>
This is the recommended and most flexible approach for passing variables from frontmatter to client-side scripts in Astro Pass frontmatter variables to scripts.
2. Using define:vars Directive
You can use the define:vars directive to pass JSON-serializable frontmatter variables directly into a <script> tag. The variable will be available as a global variable in the script:
---
// Frontmatter
const message = "Astro is awesome!";
---
<script define:vars={{ message }}>
alert(message);
</script>
Note: Using define:vars on a <script> tag implies the is:inline directive, so your script will be inlined and not bundled define:vars.
Summary:
- Use
data-*attributes for maximum flexibility and when you want to attach data to specific elements. - Use
define:varsfor simple cases where you want to inject variables directly into an inline script.
Let me know if you need an example for a specific use case!
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@urban owl Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@noble widget I went with the second method. How can I resolve Type assertion expressions can only be used in TypeScript files. from the as HTMLSelectElement.
Let me check the knowledge base for you again. One moment! :books:
The error message “Type assertion expressions can only be used in TypeScript files.” occurs when you use a TypeScript type assertion (e.g., as HTMLSelectElement) inside a <script> tag in an Astro component, but the script is being processed as JavaScript, not TypeScript.
According to the Astro documentation, all scripts in <script> tags are TypeScript by default only if the script is processed by Astro (i.e., the script tag has no attributes other than src). However, when you use the define:vars directive, Astro treats the script as inline and does not process it as TypeScript—so type assertions are not allowed and will cause this error Script processing define:vars.
How to resolve:
- Remove the type assertion and use a type-safe approach in plain JavaScript, such as a runtime check or type guard:
<script define:vars={{ message }}>
const select = document.getElementById('my-select');
if (select instanceof HTMLSelectElement) {
// Now TypeScript/JS knows select is an HTMLSelectElement
select.value = 'someValue';
}
</script>
Summary:
You cannot use TypeScript type assertions (as HTMLSelectElement) in inline scripts with define:vars. Use runtime checks like instanceof instead.