Lists

`.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.

3 min read Level 1/5 #astro#lists#map
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 →