`.map()` Is Still How You Turn Arrays Into UI
Lists
Astro's template renders arrays the same way JSX does — map each item to an element. No `key` needed, unlike React.
What you'll learn
- Map arrays to elements
- Handle empty lists
- Skip `key` (Astro doesn't need it)
To render an array, .map() it to JSX-like elements. The template
sees the array and renders each item.
Basic Pattern
---
const tags = ["js", "astro", "frontend"];
---
<ul>
{tags.map(tag => <li>{tag}</li>)}
</ul> No key Required
Astro renders to plain HTML — there’s no virtual DOM to reconcile,
so it doesn’t need key props.
However: if your .map() is inside a hydrated framework
component (React/Vue/Svelte island), the usual key rules apply
for THAT framework.
Empty State
[].map(...) renders nothing, so handle empty explicitly:
---
const { posts } = Astro.props;
---
{posts.length === 0 ? (
<p>No posts yet.</p>
) : (
<ul>
{posts.map(p => <li><a href={`/posts/${p.slug}`}>{p.title}</a></li>)}
</ul>
)} Filtering And Mapping
{posts
.filter(p => p.published)
.map(p => <li>{p.title}</li>)} With Index
{items.map((item, i) => (
<li>{i + 1}. {item}</li>
))} Inline vs Sub-Component
When the per-item markup is trivial, inline. When it gets longer, extract:
---
import PostCard from "./PostCard.astro";
---
<div class="grid">
{posts.map(post => <PostCard post={post} />)}
</div> Up Next
Fragments — group elements without an extra DOM wrapper.
Fragments →