Fix: Invalid Component Arguments in Astro

Error message:
Invalid component arguments.
Components & Hydration 2025-01-25

What Causes This Error?

This error occurs when you try to call an Astro component as a function instead of using it in the template markup. Astro components must be rendered using JSX-like syntax, not function calls.

The Problem

---
import Card from '../components/Card.astro';

// ❌ Can't call component as function
const result = Card({ title: 'Hello' });

// ❌ Can't use component in expressions this way
const cards = items.map(item => Card({ title: item.title }));
---

The Fix

Use Component in Template

---
import Card from '../components/Card.astro';
---

<!-- ✅ Use in template markup -->
<Card title="Hello" />

Map Over Items in Template

---
import Card from '../components/Card.astro';

const items = [
  { title: 'First' },
  { title: 'Second' },
  { title: 'Third' },
];
---

<!-- ✅ Map in template -->
{items.map((item) => (
  <Card title={item.title} />
))}

Common Scenarios

Dynamic Component Rendering

---
import Card from '../components/Card.astro';
import Banner from '../components/Banner.astro';

const showBanner = true;
---

<!-- ✅ Conditional rendering in template -->
{showBanner && <Banner />}
<Card title="Content" />

Slots and Children

---
import Wrapper from '../components/Wrapper.astro';
---

<!-- ✅ Pass children via slots -->
<Wrapper>
  <p>This is the content</p>
</Wrapper>

Props Spreading

---
import Button from '../components/Button.astro';

const buttonProps = {
  label: 'Click me',
  variant: 'primary',
  disabled: false,
};
---

<!-- ✅ Spread props in template -->
<Button {...buttonProps} />

Repeated Components

---
import ListItem from '../components/ListItem.astro';

const todos = [
  { id: 1, text: 'Learn Astro', done: true },
  { id: 2, text: 'Build site', done: false },
];
---

<ul>
  {todos.map((todo) => (
    <ListItem key={todo.id} text={todo.text} done={todo.done} />
  ))}
</ul>

Nested Components

---
import Layout from '../layouts/Layout.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
---

<Layout>
  <Header />
  <main>
    <slot />
  </main>
  <Footer />
</Layout>

Named Slots

---
import Card from '../components/Card.astro';
---

<Card>
  <span slot="header">Card Title</span>
  <p>Card content goes here</p>
  <span slot="footer">Card footer</span>
</Card>

Dynamic Component Selection

---
import CardA from '../components/CardA.astro';
import CardB from '../components/CardB.astro';

const useAlternate = true;
const CardComponent = useAlternate ? CardB : CardA;
---

<!-- ✅ Can use dynamic component reference -->
<CardComponent title="Dynamic" />

Quick Checklist

  • Components must be used in template, not called as functions
  • Use {items.map(...)} for lists in template
  • Use {condition && <Component />} for conditionals
  • Spread props with {...props} syntax
  • Pass children via default slot or named slots