Astro components are the basic building blocks of any Astro project. They are HTML-only templating components with no client-side runtime.
If you know HTML, you already know enough to write your first Astro component.
Astro components are extremely flexible. Often, an Astro component will contain some reusable UI on the page, like a header or a profile card. At other times, an Astro component may contain a smaller snippet of HTML, like a collection of common
<meta> tags that make SEO easy to work with. Astro components can even contain an entire page layout.
Component StructureSection titled Component Structure
An Astro component is made up of two main parts: the Component Script and the Component Template. Each part performs a different job, but together they aim to provide a framework that is both easy to use and expressive enough to handle whatever you might want to build.
You can use components inside of other components, to build more and more advanced UI. For example, a
Button component could be used to create a
ButtonGroup component like so:
The Component ScriptSection titled The Component Script
Astro uses a code fence (
---) to identify the component script in your Astro component. If you’ve ever written Markdown before, you may already be familiar with a similar concept called frontmatter. Astro’s idea of a component script was directly inspired by this concept.
- importing other Astro components
- importing other framework components, like React
- importing data, like a JSON file
- fetching content from an API or database
- creating variables that you will reference in your template
The Component TemplateSection titled The Component Template
Below the component script, sits the component template. The component template decides the HTML output of your component.
If you write plain HTML here, your component will render that HTML in any Astro page it is imported and used.
JSX-like ExpressionsSection titled JSX-like Expressions
VariablesSection titled Variables
Local variables can be added into the HTML using the curly braces syntax:
Dynamic AttributesSection titled Dynamic Attributes
Local variables can be used in curly braces to pass attribute values to both HTML elements and components:
Dynamic HTMLSection titled Dynamic HTML
Local variables can be used in JSX-like functions to produce dynamically-generated HTML elements:
Astro can conditionally display HTML using JSX logical operators and ternary expressions.
Dynamic TagsSection titled Dynamic Tags
You can also use dynamic tags by setting a variable to an HTML tag name or a component import:
When using dynamic tags:
Variable names must be capitalized. For example, use
element. Otherwise, Astro will try to render your variable name as a literal HTML tag.
Hydration directives are not supported. When using
client:*hydration directives, Astro needs to know which components to bundle for production, and the dynamic tag pattern prevents this from working.
Fragments & Multiple ElementsSection titled Fragments & Multiple Elements
An Astro component template can render multiple elements with no need to wrap everything in a single
<Fragment> </Fragment> or the shorthand
Fragments can also be useful to avoid wrapper elements when adding
set:* directives, as in the following example:
Differences between Astro and JSXSection titled Differences between Astro and JSX
Astro component syntax is a superset of HTML. It was designed to feel familiar to anyone with HTML or JSX experience, but there are a couple of key differences between
.astro files and JSX.
AttributesSection titled Attributes
In Astro, you use the standard
kebab-case format for all HTML attributes instead of the
camelCase used in JSX. This even works for
class, which is not supported by React.
CommentsSection titled Comments
Component PropsSection titled Component Props
An Astro component can define and accept props. These props then become available to the component template for rendering HTML. Props are available on the
Astro.props global in your frontmatter script.
Here is an example of a component that receives a
greeting prop and a
name prop. Notice that the props to be received are destructured from the global
This component, when imported and rendered in other Astro components, layouts or pages, can be passed these props as attributes:
You can also define your props with TypeScript with a
Props type interface. Astro will automatically pick up the
Props interface in your frontmatter and give type warnings/errors. These props can also be given default values when destructured from
Component props can be given default values to use when none are provided.
SlotsSection titled Slots
<slot /> element is a placeholder for external HTML content, allowing you to inject (or “slot”) child elements from other files into your component template.
By default, all child elements passed to a component will be rendered in its
This pattern is the basis of an Astro layout component: an entire page of HTML content can be “wrapped” with
<Layout></Layout> tags and sent to the Layout component to render inside of common page elements.
Named SlotsSection titled Named Slots
An Astro component can also have named slots. This allows you to pass only HTML elements with the corresponding slot name into a slot’s location.
slot="my-slot" attribute on the child element that you want to pass through to a matching
<slot name="my-slot" /> placeholder in your component.
Fallback Content for SlotsSection titled Fallback Content for Slots
Slots can also render fallback content. When there are no matching children passed to a slot, a
<slot /> element will render its own placeholder children.
CSS StylesSection titled CSS Styles
<style> tags are also supported inside of the component template.
They can be used to style your components, and all style rules are automatically scoped to the component itself to prevent CSS conflicts in large apps.
📚 See our Styling Guide for more information on applying styles.
Client-Side ScriptsSection titled Client-Side Scripts
<script> tags are processed by Astro.
- Any imports will be bundled, allowing you to import local files or Node modules.
- The processed script will be injected into your page’s
- TypeScript is fully supported, including importing TypeScript files
- If your component is used several times on a page, the script tag will only be included once.
To avoid bundling the script, you can use the
<script> tags can be used in the same
.astro file using any combination of the methods above.
📚 See our directives reference page for more information about the directives available on
Loading External ScriptsSection titled Loading External Scripts
import method described below.
Using Hoisted ScriptsSection titled Using Hoisted Scripts
When to use this: If your external script lives inside of
src/ and it supports the ESM module type.
HTML ComponentsSection titled HTML Components
Astro supports importing and using
.html files as components or placing these files within the
src/pages subdirectory as pages. You may want to use HTML components if you’re reusing code from an existing site built without a framework, or if you want to ensure that your component has no dynamic features.
HTML components must contain only valid HTML, and therefore lack key Astro component features:
- They don’t support frontmatter, server-side imports, or dynamic expressions.
<script>tags are left unbundled, treated as if they had
- They can only reference assets that are in the
Next StepsSection titled Next Steps
📚 Read about Astro’s built-in components.