---
layout: ~/layouts/Main.astro
title: Astro Components
---
## ✨ `.astro` Syntax
Astro comes with its own server-side, component-based templating language. Think of it as HTML enhanced with the full power of JavaScript.
Learning a new syntax can be intimidating, but the `.astro` format has been carefully designed with familiarity in mind. It borrows heavily from patterns you likely already know—components, Frontmatter, and JSX-like expressions. We're confident that this guide will help you feel comfortable writing `.astro` files in no time.
---
### The `.astro` format
If you're already familiar with **HTML or JavaScript**, you'll likely feel comfortable with `.astro` files right away.
Think of `.astro` as **component-oriented HTML**. Components are reusable, self-contained blocks of HTML and CSS that belong together.
```html
Document
Hello world!
```
```html
Hello world!
```
Developers have come up with a myriad of different techniques for composing blocks of HTML over the years, but far and away the most successful has been [JSX](https://reactjs.org/docs/introducing-jsx.html).
We love JSX! In fact, `.astro` files borrow the highly-expressive expression syntax directly from JSX.
```jsx
Hello {name}!
{items.map((item) => (
- {item}
))}
So good!
```
`.astro` files also borrow the concept of [Frontmatter](https://jekyllrb.com/docs/front-matter/) from Markdown. Instead of introducing a new HTML-oriented `import` and `export` syntax, `.astro` just uses JavaScript.
```jsx
---
// This area is TypeScript (and therefore JavaScript)!
import MyComponent from './MyComponent.astro'
---
Document
```
### Data and Props
`.astro` components can define local variables inside of the Frontmatter script. These are automatically exposed to the content below.
```jsx
---
let name = 'world';
---
Hello {name}!
```
`.astro` components can also accept props when they are rendered. Public props are exposed on the `Astro.props` global.
```jsx
---
const { greeting = 'Hello', name } = Astro.props;
---
{greeting} {name}!
```
To define the props which your component accepts, you may export a TypeScript interface or type named `Props`.
```tsx
---
export interface Props {
name: string;
greeting?: string;
}
const { greeting = 'Hello', name } = Astro.props;
---
{greeting} {name}!
```
### Slots
`.astro` files use the [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot) element to enable component composition. Coming from React, this is the same concept as `children`. You can think of the `` element as a placeholder for markup which will be passed from outside of the component.
```astro
Hello world!
```
Slots are especially powerful when using **named slots**. Rather than a single `` element which renders _all_ children, named slots allow you to specify where certain children should be placed.
> **Note** The `slot` attribute is not restricted to plain HTML, components can use `slot` as well!
```astro
Hello world!
Lorem ipsum ...
```
Slots also have the ability to render **fallback content**. When there are no matching children passed to a ``, a `` element will be replaced with its own children.
```astro
I will render when this slot does not have any children!
```
### Fragments
At the top-level of an `.astro` file, you may render any number of elements.
```html
```
Inside of an expression, you must wrap multiple elements in a Fragment. Fragments must open with `<>` and close with `>`.
```jsx
{[0, 1, 2].map((id) => (
<>
>
))}
```
### `.astro` versus `.jsx`
`.astro` files can end up looking very similar to `.jsx` files, but there are a few key differences. Here's a comparison between the two formats.
| Feature | Astro | JSX |
| ---------------------------- | ------------------------------------------ | -------------------------------------------------- |
| File extension | `.astro` | `.jsx` or `.tsx` |
| User-Defined Components | `` | `` |
| Expression Syntax | `{}` | `{}` |
| Spread Attributes | `{...props}` | `{...props}` |
| Children | `` (with named slot support) | `children` |
| Boolean Attributes | `autocomplete` === `autocomplete={true}` | `autocomplete` === `autocomplete={true}` |
| Inline Functions | `{items.map(item => {item})}` | `{items.map(item => {item})}` |
| IDE Support | WIP - [VS Code][code-ext] | Phenomenal |
| Requires JS import | No | Yes, `jsxPragma` (`React` or `h`) must be in scope |
| Fragments | Automatic top-level, `<>` inside functions | Wrap with `` or `<>` |
| Multiple frameworks per-file | Yes | No |
| Modifying `` | Just use `` | Per-framework (``, ``, etc) |
| Comment Style | `` | `{/* JavaScript */}` |
| Special Characters | ` ` | `{'\xa0'}` or `{String.fromCharCode(160)}` |
| Attributes | `dash-case` | `camelCase` |
### URL resolution
It’s important to note that Astro **won’t** transform HTML references for you. For example, consider an `` tag with a relative `src` attribute inside `src/pages/about.astro`:
```html
```
Since `src/pages/about.astro` will build to `/about/index.html`, you may not have expected that image to live at `/about/thumbnail.png`. So to fix this, choose either of two options:
#### Option 1: Absolute URLs
```html
```
The recommended approach is to place files within `public/*`. This references a file it `public/thumbnail.png`, which will resolve to `/thumbnail.png` at the final build (since `public/` ends up at `/`).
#### Option 2: Asset import references
```jsx
---
// ✅ Correct: references src/thumbnail.png
import thumbnailSrc from './thumbnail.png';
---
```
If you’d prefer to organize assets alongside Astro components, you may import the file in JavaScript inside the component script. This works as intended but this makes `thumbnail.png` harder to reference in other parts of your app, as its final URL isn’t easily-predictable (unlike assets in `public/*`, where the final URL is guaranteed to never change).
[code-ext]: https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode