Using Props with Svelte

Props, popular with other frameworks such as React and Vue.js, are a very efficient way to enable component communication. Props are used in Svelte as you’d expect. They are passed top-down from parent components to children and are used to specify data that the component can consume to inform what it renders in the DOM.

Let’s demonstrate how to make use of props by building a simple Card component:

<script>
  export let title;
  export let description;
  export let imageUrl;
</script>

<style>
  h1 {
    color: coral;
  }
  section {
    border-radius: 8px;
    box-shadow: 0 0 4px rgba(255, 0, 0, 0.1);
    max-width: 600px;
    margin: 1rem auto;
    padding: 1rem 2rem;
  }
  img {
    width: 32px;
    height: 32px;
    margin-right: 12px;
    vertical-align: middle;
  }
</style>

<section>
  <h1>
    <img src={imageUrl} alt="Avatar for {title}" />
     {title}
  </h1>

  <p>{description}</p>
</section>

As you can see, you let Svelte know about the props that a component accepts by using the ES6 export syntax. You can then make use of the props inside the component with simple value interpolation.

You can then make use of the component by providing the props like this:

Parent.svelte

<script>
  import Card from "./Card.svelte";
</script>

<Card
  title="See you later, Alligator"
  imageUrl="https://alligator.io/images/alligator-logo3.svg"
  description="Not so soon, baboon!" />

Default Values for Optional Props

With our current setup, if we fail to pass in a prop, Svelte will complain with a warning in the console:

<script>
  import Card from "./Card.svelte";
</script>

<Card
  title="See you later, Alligator"
  description="Not so soon, baboon!" />

With this, the warning will be: <Card> was created without expected prop 'imageUrl'.

To fix that, we can provide a default value for any prop declared, using something like this:

<script>
  export let title;
  export let description = "Description coming soon!";
  export let imageUrl = "https://picsum.photos/64";
</script>

<style>
  /* ... */
</style>

<section>
  <h1>
    <img src={imageUrl} alt="Avatar for {title}" />
     {title}
  </h1>

  <p>{description}</p>
</section>

And now you can use the Card component without passing-in a description or imageUrl and the component will revert to the default values:

<script>
  import Card from "./Card.svelte";
</script>

<Card
  title="Tood-a-loo, Kangaroo!" />

Spreading Props

Similar to how you can spread props in JSX, Svelte allows you to spread props from an object in your code, to avoid the extra typing.

Here’s an example where spreading props is compared against typing in the props in the long form:

<script>
  import Card from "./Card.svelte";

  const items = [
    {
      id: 1
      title: "Pirate",
      description: "Argg!!",
      imageUrl: "https://alligator.io/images/pirate.svg"
    },
    {
      id: 2
      title: "Chef",
      description: "À la soupe!",
      imageUrl: "https://alligator.io/images/chef.svg"
    }
  ];
</script>

<!-- Without spread: -->
{#each items as item}
  <Card
    title={item.title}
    description={item.description}
    imageUrl={item.imageUrl}
  />
{/each}

<!-- With spread: -->
{#each items as item}
  <Card {...item} />
{/each}

Note how it doesn’t matter that when we spread the props from our objects in items an extra property (id) is also passed-in. The Card component doesn’t declare it’s use of id as a prop, so it’s just ignored.

As you can see in the above example, I'm also making use of an each block for logic inside my markup. I'll cover what Svelte makes available for logic in components in a future post, but you can also read all about it in the Svelte tutorial

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#