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
.astrofile. - 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
PostCardcomponent 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.
PostCardis used three times. Each time it gets a differenttitleanddate.- 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:
- The two parts of an
.astrofile. - How to show values with
{ }expressions. - How to set attributes from values.
- How to show something only when a condition is true.
- How to make a list from an array with
map(). - What fragments and dynamic tags are.
- How to pass props, read them and give them default values.
- 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 ofname.- 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}istrue, so the button is disabled.- When an attribute's value is
false,nullorundefined, 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 whenisNewis 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 whileisAvailableis true.? :picks the last sentence from the number of skills.nullshows 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
levelto3, 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.propsis 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.propsis 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
interfacenamedPropsin 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 Propsblock 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, notpost-card.
Composing Components
- Composing = building a component from other components.
- A
PostListcan usePostCardmany times. A page can usePostList. - 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
- Component = a reusable piece of a page in an
.astrofile. - Component script = code between the
---lines. Runs at build time. - Template = HTML plus
{ }expressions. - Attribute value =
href={link}, with no quotes. Conditions:
{ok && <p>Yes</p>}shows or hides.{ok ? <A /> : <B />}picks one.
- List =
{items.map((item) => <li>{item}</li>)}. Nokeyneeded. - Fragment =
<>...</>. Groups without a tag. - Props = values passed in. Read with
Astro.props. Defaults with=. - [TS]
interface Propsdescribes the props.
Common mistakes
| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
href="{link}" | Quotes are needed | Write href={link} | The page links to the text {link} |
| Lower-case component name | Any name works | Import and use PostCard, with a capital | Astro outputs an unknown <postcard> tag |
| Forgetting the import | Components are found by themselves | Import every component in the script | Build error: the name is not defined |
{if (ok) ...} in the template | Any JavaScript works in { } | Use && or ? : | The build fails |
| Expecting a variable to update on click | The script runs in the browser | The script runs once, at build time | The page never changes |
| No default for an optional prop | Missing props are empty text | Use = "default" | The page shows undefined or nothing |
Check Yourself
Exercises
What to Remember
- An
.astrofile has a script (build time) and a template (HTML). - Use
{ }for values,&&and? :for conditions, andmap()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.