astro-sintaxis-componentes

Astro Component Syntax

  • 5 min

We’ve already installed Astro and seen the folders that make up a project. Now let’s “open the hood” and learn how to write code in Astro.

As with many frameworks, the basic building block in Astro is the component (in this case, files with the .astro extension).

The syntax will look suspiciously familiar. If you know HTML and a little JavaScript, you already know 90% of Astro. However, it has its own rules we need to know.

An Astro component is divided into two parts:

  • The Component Script (Frontmatter or Code Fence)
  • The Component Template (HTML).

.astro components are an exclusive templating language. They cannot be used in other frameworks like React or Vue, but they can contain components from those frameworks.

The Frontmatter

At the top of a .astro file, you’ll see a block delimited by three dashes ---. This is what we call the component’s Frontmatter or Code Fence.

---
// All this is JavaScript (or TypeScript)
// It runs on the SERVER or at BUILD time.
const title = "Hello Astro";
const number = 42;

console.log("This appears in the server terminal, NOT in the browser");
---
Copied!

This is where we write the logic needed to prepare our template.

Key features of the Code Fence:

  1. Server Execution: The code you write here NEVER reaches the user’s browser. Astro executes it, generates the resulting HTML, and throws the code away.
  2. Security: Since it doesn’t go to the client, you can safely use secret environment variables (API KEYS, database passwords).
  3. Imports: Here we will import other components, JSON data, or functions.
---
import Header from '../components/Header.astro';
import { getData } from '../lib/api';

const data = await getData(); // Supports top-level await!
---
Copied!

See that await outside an async function? Astro supports Top-Level Await by default in the frontmatter. It’s super convenient for fetching data.

The component template

Below the second set of dashes --- is the template. Here we define the HTML that will be rendered.

Unlike static HTML, here we can use JavaScript logic directly in the HTML to render conditional content or lists.

If you come from React, you’ll feel right at home because it uses a JSX-like syntax.

If you come from pure HTML, it won’t be difficult either, because in the end it’s just a superset of HTML.

Variable Injection

We can inject any variable defined in the Code Fence using curly braces {}.

---
const name = "Luis";
---

<h1>Hello, {name}</h1>
Copied!

Conditional Rendering

We don’t use v-if (Vue) or *ngIf (Angular). We use standard JavaScript logic.

Logical AND operator (&&): Useful for showing something if a condition is true.

---
const isVisible = true;
---

{isVisible && <p>This message is visible.</p>}
Copied!

Ternary Operator: Useful for showing one thing or another.

---
const userLoggedIn = false;
---

{userLoggedIn ? <button>Logout</button> : <button>Login</button>}
Copied!

List Rendering

To repeat elements, we use the .map() function of JavaScript arrays.

---
const technologies = ['Astro', 'React', 'TypeScript'];
---

<ul>
  {technologies.map((tech) => (
    <li>{tech}</li>
  ))}
</ul>
Copied!

Unlike React, in Astro it is not strictly mandatory to use the key prop in lists, although it remains a good practice if you are going to manipulate the DOM later.

Attributes

Just like in HTML, we can pass attributes to tags.

<div id="container" data-type="main">...</div>
Copied!

But we can also pass dynamic attributes:

---
const dynamicClass = "red";
const image = "/img/photo.png";
---
<img src={image} class={dynamicClass} />
Copied!

Differences from standard HTML and React JSX

Although it’s very similar, there are important nuances that make our lives easier.

class vs className

If you come from React, you know that class is a reserved word and you have to use className.

In Astro we use class, just like in standard HTML (finally!).

<div class="my-class">Correct in Astro</div>
Copied!

Fragments

In Astro you don’t need to wrap everything in a single parent <div>. A component can return multiple root elements.

---
// Header.astro component
---

<h1>Title</h1>
<p>Subtitle</p>
Copied!

Comments

Inside the template you can use standard HTML comments, but be careful: these do reach the browser.

If you want to put comments that do not appear in the final source code (for development notes), use the JS syntax inside curly braces:

{/* This comment is only for you, it's removed during compilation */}
Copied!

The <style> and <script> tags

In Astro, if you put a <style> tag inside the component, the styles are Scoped (local) by default.

They won’t affect other components. The same applies to <script>.