Component Props

Loading concept...

🎁 Svelte Component Props: The Gift-Giving Guide

Imagine components are like friends at a birthday party. Props are the gifts you give them to make them special!


🌟 The Big Picture

Every Svelte component can receive props β€” special pieces of information passed from a parent component. Think of it like this:

  • Parent Component = You (the gift giver)
  • Child Component = Your friend (the gift receiver)
  • Props = The gifts you bring!

Without props, every component would be identical and boring. Props make each one unique!


πŸ“¦ Declaring Props

What is it?

Telling your component: β€œHey, I’m expecting a gift!”

The Simple Way

In Svelte 5, we use the $props() rune to declare what gifts we expect:

<script>
  let { name } = $props();
</script>

<p>Hello, {name}!</p>

Real-Life Example

Imagine a greeting card component. It needs to know WHO to greet:

<!-- GreetingCard.svelte -->
<script>
  let { recipientName } = $props();
</script>

<div class="card">
  Dear {recipientName},
  Happy Birthday! πŸŽ‚
</div>

Using it:

<GreetingCard recipientName="Sarah" />

Result: β€œDear Sarah, Happy Birthday! πŸŽ‚β€


πŸŽ€ Default Prop Values

What is it?

Sometimes your friend forgets to bring a gift. No problem! You can set a backup gift (default value).

How it works

<script>
  let { color = "blue" } = $props();
</script>

<div style="background: {color}">
  I'm {color}!
</div>

If someone uses <MyBox /> without a color prop, it’s blue! If they use <MyBox color="red" />, it’s red!

Think of it like…

A pizza order form:

  • Default size = Medium
  • Default crust = Regular
  • You only change what you want different!
<script>
  let {
    size = "medium",
    crust = "regular",
    toppings = ["cheese"]
  } = $props();
</script>

✨ The $props Rune

What is a Rune?

Runes are special Svelte 5 keywords that start with $. They’re like magic spells that give your code superpowers!

$props() β€” The Gift Receiver Spell

<script>
  // πŸͺ„ This magic spell receives all gifts!
  let { title, count, isActive } = $props();
</script>

Why is it special?

  1. Clean syntax β€” One line declares everything
  2. Destructuring β€” Pick exactly what you need
  3. Type-friendly β€” Works great with TypeScript

Multiple Props Example

<script>
  let {
    username,
    score = 0,
    level = 1,
    isOnline = false
  } = $props();
</script>

<div class="player-card">
  <h3>{username}</h3>
  <p>Score: {score}</p>
  <p>Level: {level}</p>
  <span>{isOnline ? '🟒' : '⚫'}</span>
</div>

πŸ”— The $bindable Rune

What is it?

Normal props are like giving a photo β€” your friend can look but can’t change the original. $bindable is like giving a shared notebook β€” changes go both ways!

The Magic of Two-Way Binding

<!-- Parent.svelte -->
<script>
  let userName = "Alex";
</script>

<ChildInput bind:value={userName} />
<p>Parent sees: {userName}</p>
<!-- ChildInput.svelte -->
<script>
  let { value = $bindable() } = $props();
</script>

<input bind:value />

How it works

graph TD A[Parent: userName = Alex] -->|passes down| B[Child: value] B -->|user types Ben| C[Child updates value] C -->|$bindable syncs back| D[Parent: userName = Ben]

Real Example: A Counter

<!-- Parent -->
<script>
  let count = 0;
</script>

<Counter bind:count />
<p>Count is: {count}</p>
<!-- Counter.svelte -->
<script>
  let { count = $bindable(0) } = $props();
</script>

<button onclick={() => count++}>
  Add One ({count})
</button>

Click the button in the child β†’ parent’s count updates too!


⚑ Prop Reactivity

What is it?

When a prop changes, your component automatically updates. Like magic!

The Flow

graph TD A[Parent changes prop] --> B[Svelte detects change] B --> C[Child re-renders] C --> D[User sees update instantly]

Example: Live Score

<!-- Parent -->
<script>
  let score = 0;
</script>

<button onclick={() => score++}>
  Goal! ⚽
</button>

<Scoreboard currentScore={score} />
<!-- Scoreboard.svelte -->
<script>
  let { currentScore } = $props();
</script>

<div class="board">
  SCORE: {currentScore}
</div>

Every time you click β€œGoal!”, the scoreboard updates automatically!

Important Rule

Props flow downward like a waterfall:

  • Parent β†’ Child βœ…
  • Child β†’ Parent ❌ (unless using $bindable)

🌊 Spread Props

What is it?

Instead of passing props one by one, spread them all at once! Like dumping a whole bag of gifts.

The Problem It Solves

Without spread (tedious):

<UserCard
  name={user.name}
  age={user.age}
  email={user.email}
  avatar={user.avatar}
  bio={user.bio}
/>

With spread (elegant):

<UserCard {...user} />

How It Works

<script>
  let buttonProps = {
    disabled: false,
    type: "submit",
    class: "primary"
  };
</script>

<!-- These are the same! -->
<button {...buttonProps}>Click</button>

<button
  disabled={false}
  type="submit"
  class="primary"
>Click</button>

Combining Spread with Extras

<script>
  let baseStyles = { color: "blue" };
</script>

<!-- Spread + override -->
<Box {...baseStyles} color="red" />

The color will be β€œred” because explicit props override spread!


🧩 Object Destructuring in Props

What is it?

Unpacking a gift box to grab exactly what you want inside!

Basic Destructuring

<script>
  // Instead of: let props = $props();
  // We destructure directly:
  let { name, age, city } = $props();
</script>

With Defaults

<script>
  let {
    title = "Untitled",
    items = [],
    showHeader = true
  } = $props();
</script>

Nested Destructuring

When a prop is an object itself:

<script>
  let {
    user: { name, email } = {}
  } = $props();
</script>

<p>{name} ({email})</p>

Renaming While Destructuring

<script>
  // Prop comes as "data", we call it "items"
  let { data: items = [] } = $props();
</script>

{#each items as item}
  <li>{item}</li>
{/each}

πŸŽ’ Rest Props Pattern

What is it?

Grab some specific gifts, then put everything else in a β€œrest” bag!

The Syntax

<script>
  let { name, age, ...rest } = $props();
</script>
  • name and age = specific props you want
  • ...rest = everything else bundled together

Why Use It?

Perfect for wrapper components!

<!-- CustomButton.svelte -->
<script>
  let { variant = "primary", ...rest } = $props();
</script>

<button
  class="btn btn-{variant}"
  {...rest}
>
  <slot />
</button>

Using it:

<CustomButton
  variant="danger"
  disabled
  onclick={handleClick}
  aria-label="Delete"
>
  Delete
</CustomButton>

The variant is used for styling. Everything else (disabled, onclick, aria-label) passes through to the actual <button>!

Real-World Pattern

<!-- Input.svelte -->
<script>
  let {
    label,
    error,
    ...inputProps
  } = $props();
</script>

<div class="form-field">
  <label>{label}</label>
  <input {...inputProps} />
  {#if error}
    <span class="error">{error}</span>
  {/if}
</div>
<!-- Usage -->
<Input
  label="Email"
  type="email"
  placeholder="you@example.com"
  required
  error={emailError}
/>

🎯 Quick Reference

Pattern Use Case
let { x } = $props() Basic prop declaration
let { x = 5 } = $props() Prop with default
let { x = $bindable() } = $props() Two-way binding
<Child {...obj} /> Spread all props
let { a, ...rest } = $props() Rest pattern

πŸš€ You Did It!

You now understand the 8 key patterns for Svelte component props:

  1. βœ… Declaring Props β€” Tell components what to expect
  2. βœ… Default Values β€” Set fallbacks for missing props
  3. βœ… $props Rune β€” The magic spell to receive props
  4. βœ… $bindable Rune β€” Enable two-way communication
  5. βœ… Prop Reactivity β€” Automatic updates when props change
  6. βœ… Spread Props β€” Pass many props at once
  7. βœ… Object Destructuring β€” Pick exactly what you need
  8. βœ… Rest Props β€” Capture the leftovers

Props are the secret sauce that makes Svelte components flexible and reusable. Now go build something amazing! πŸŽ‰

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.