Component Basics

By Syncfusion®, Inc. · Last updated

The .astro file format, the component script and template, expressions, dynamic attributes, conditional rendering, lists with map(), fragments, dynamic tags, props with defaults and spreading, and importing components.

Astro Components

  • An Astro component is a reusable piece of a page, saved in an .astro file.
  • A header, a blog card and a footer are all components.
  • You build a page by putting small components together, like building blocks.
  • In this lesson, you will write components and pass data into them.

Simple lesson: write a piece of page once as a component, then reuse it everywhere.

A Real-World Example

  • Asha's home page lists her three newest posts.
  • Each post shows a title, a date and a short summary in the same box shape.
  • Writing the same box three times is slow, and a change must be made three times.
  • So she writes one PostCard component and uses it three times, with different data.

Press ▶ Run. Then open PostCard.astro and change the box.

What happened:

  • The page imports three components and uses them like HTML tags.
  • PostCard is used three times. Each time it gets a different title and date.
  • The HTML sent to browser view shows three finished <article> boxes. The components are gone.

What You Will Learn

In this lesson, you will learn:

  1. The two parts of an .astro file.
  2. How to show values with { } expressions.
  3. How to set attributes from values.
  4. How to show something only when a condition is true.
  5. How to make a list from an array with map().
  6. What fragments and dynamic tags are.
  7. How to pass props, read them and give them default values.
  8. How to import and organise components.

Component Anatomy

The .astro File Format

An .astro file has two parts:

  • Component script = the code between the two --- lines at the top.
  • Component template = the HTML-like part below the second ---.
  • The two --- lines are called the code fence. Some people call the script part the frontmatter.

An .astro file: the component script between two fence lines runs at build time. The template below becomes HTML.

--- const name = "Asha"; const posts = 3; --- <h1>Hi, name</h1> <p>posts posts</p>

Component script JavaScript or TypeScript Runs at build time, not in the browser Component template HTML plus expressions Becomes the HTML of the page

The script prepares the data. The template shows it.

The Component Script

  • It is written in JavaScript or TypeScript.
  • Use it to make variables, import components and read data.
  • It runs when the page is built. It never runs in the visitor's browser.
  • So it can safely read files or secret keys.

The script is private, but the template is public. If you write a secret key into the template, it is in the HTML that every visitor downloads.

The Component Template

  • It looks like HTML.
  • Inside { }, you can use the variables from the script.
  • It can be plain HTML with no script at all. Then the two --- lines are optional.

Simple lesson: the script prepares, the template shows.

Template Expressions

Variables and Expressions

  • Expression = a piece of JavaScript inside { } in the template.
  • {name} shows the value of name.
  • You can also do small sums or calls: {posts * 2}, {name.toUpperCase()}.

Dynamic Attributes

  • An attribute can take a value too: <a href={link}>.
  • Write {link} with no quotes around it.
  • With quotes, "{link}" is plain text. Astro does not fill it in.

Press ▶ Run. Then change the values in the script and run again.

  • title={name + " on GitHub"} builds the text from a variable.
  • disabled={!isHiring} is true, so the button is disabled.
  • When an attribute's value is false, null or undefined, Astro leaves the attribute out.

Simple lesson: use { } for any value that comes from your script, in text or in attributes.

Conditions and Lists

Conditional Rendering

  • Conditional rendering = show something only when a condition is true.
  • {isNew && <span>New</span>} shows the span only when isNew is true.
  • {online ? <p>Online</p> : <p>Away</p>} picks one of two things.

Rendering Lists with map()

  • map() turns each item of an array into a piece of HTML.
  • {skills.map((skill) => <li>{skill}</li>)} makes one <li> per skill.
  • Astro does this at build time. The browser gets finished <li> tags.

Animation: each item of the array HTML, CSS, Astro moves through map and becomes one li tag.

Array map() HTML

"HTML" "CSS" "Astro"

<li>HTML</li>

<li>CSS</li>

<li>Astro</li>

skill => <li>

map() visits each item and returns one piece of HTML for it.

Press ▶ Run. Then set isAvailable to false and add a skill to the array.

  • && shows the badge only while isAvailable is true.
  • ? : picks the last sentence from the number of skills.
  • null shows nothing.

In Astro, a list made with map() needs no key attribute. Astro builds HTML once and never updates it, so it does not need keys to track items.

Simple lesson: && for "show or hide", ? : for "this or that", map() for lists.

Fragments and Dynamic Tags

Fragments

  • Fragment = a wrapper that groups elements but adds no HTML tag of its own.
  • Write it as <>...</> or <Fragment>...</Fragment>.
  • Use it when a condition or map() must return more than one element.

Dynamic Tags

  • Dynamic tag = a tag whose name comes from a variable.
  • Store the tag name in a variable that starts with a capital letter: const Heading = "h2";.
  • Then write <Heading>Hi</Heading>. Astro makes an <h2>.
  • Change level to 3, and the heading becomes an <h3>.
  • Open HTML sent to browser. The two paragraphs have no extra wrapper around them.

Simple lesson: a fragment groups without adding a tag. A capitalised variable can be a tag name.

Props

Passing Props to Components

  • Props = values you pass into a component, like settings.
  • You pass them as attributes: <PostCard title="Hello" />.
  • Text goes in quotes. Any other value goes in { }: <PostCard likes={5} />.

Reading Astro.props

  • Inside the component, Astro.props is an object with every prop.
  • Read the ones you need: const { title, likes } = Astro.props;.

Default Values

  • A prop that is not passed is undefined.
  • Give it a default: const { tag = "General" } = Astro.props;.

Animation: the page passes title and likes to PostCard. A dot carries the values from the page into Astro.props.

index.astro (parent) <PostCard title="Hi" likes=5 />

PostCard.astro (child) Astro.props = title, likes

Props flow one way: from the parent into the child.

The parent passes props. The child reads them from Astro.props.

Spreading Props

  • {...post} passes every field of an object as a prop.
  • <PostCard {...post} /> is the same as <PostCard title={post.title} likes={post.likes} />.

[JS] Props Are Plain Objects

  • In JavaScript, Astro.props is a plain object. You do not declare anything.
  • Read the props you need and give defaults where useful.

[TS] Describing Props with interface Props

  • In TypeScript, write an interface named Props in the script.
  • Astro reads it, and your editor warns you when a prop is missing or the wrong type.
  • A ? after a name makes the prop optional: tag?: string.
interface Props {
  title: string;
  likes: number;
  tag?: string;
}

const { title, likes, tag = "General" } = Astro.props;
  • Common types: string, number, boolean, string[] (a list of text), and a choice like "draft" | "published".

Press ▶ Run. The third card has no tag, so it uses the default.

  • Switch the top bar to JavaScript. The interface Props block disappears. The component still works.

Simple lesson: pass props like attributes. Read them from Astro.props, with defaults for optional ones.

Reusing Components

Importing Components

  • Import a component in the script: import PostCard from "../components/PostCard.astro";.
  • The name you import is the tag you use. Start it with a capital letter.
  • Lower-case tags, such as <postcard>, are treated as plain HTML.

Organising the Components Folder

  • Keep small, general pieces in src/components: Button.astro, Card.astro.
  • Group bigger sets in sub-folders: src/components/blog/PostCard.astro.
  • Name files after what they show, in PascalCase: PostCard, not post-card.

Composing Components

  • Composing = building a component from other components.
  • A PostList can use PostCard many times. A page can use PostList.
  • Each piece stays small and easy to understand.

If you copy the same block of HTML a third time, stop and make it a component.

Simple lesson: small components, imported with capital names, put together into bigger ones.

TL;DR

  1. Component = a reusable piece of a page in an .astro file.
  2. Component script = code between the --- lines. Runs at build time.
  3. Template = HTML plus { } expressions.
  4. Attribute value = href={link}, with no quotes.
  5. Conditions:

    • {ok && <p>Yes</p>} shows or hides.
    • {ok ? <A /> : <B />} picks one.
  6. List = {items.map((item) => <li>{item}</li>)}. No key needed.
  7. Fragment = <>...</>. Groups without a tag.
  8. Props = values passed in. Read with Astro.props. Defaults with =.
  9. [TS] interface Props describes the props.

Common mistakes

MistakeWrong ideaCorrect ideaWhat goes wrong
href="{link}"Quotes are neededWrite href={link}The page links to the text {link}
Lower-case component nameAny name worksImport and use PostCard, with a capitalAstro outputs an unknown <postcard> tag
Forgetting the importComponents are found by themselvesImport every component in the scriptBuild error: the name is not defined
{if (ok) ...} in the templateAny JavaScript works in { }Use && or ? :The build fails
Expecting a variable to update on clickThe script runs in the browserThe script runs once, at build timeThe page never changes
No default for an optional propMissing props are empty textUse = "default"The page shows undefined or nothing

Check Yourself

Exercises

What to Remember

  • An .astro file has a script (build time) and a template (HTML).
  • Use { } for values, && and ? : for conditions, and map() for lists.
  • Props go in like attributes and come out of Astro.props.
  • Give optional props a default.
  • Import components with a capital name, then reuse them.

Next: Slots and Composition, where components wrap any content you put inside them.