Svelte.js 3 Component Props Tutorial

In this Svelte tutorial we learn how to send data from a parent component down to a child component with props.

We cover custom attributes, default & dynamic prop values, the prop shorthand and more.

Lesson Video

If you prefer to learn visually, you can watch this lesson in video format.

Lesson Project

If you want to follow along with the examples in this lesson, you’ll need a Svelte app that was cloned with degit or scaffolded with Vite

If you already have an app from previous lessons, you can use that instead.

What are Component Props in Svelte?

Props allow us to pass data from a parent component down to a child component through custom attributes on the parent component’s HTML tag.

note Props are only used for parent to child communication. If we want to communicate from the child to the parent, we use Custom Component Events .

How to create and use a component prop in Svelte

To create a prop in Svelte, we follow a simple three step process.

  1. Add a custom attribute on the component’s instance in the parent.
  2. Register the prop in the child component.
  3. Use the registered prop in some way in the child component.

For our example, we’ll use the root App component as the parent and create the following new component as the child.

  • /src/components/Child.svelte

The project should look similar to the following.

Example: project
project-folder/
├── src/
|   ├── components/
|   |   └── Child.svelte
|   └── App.svelte

The new component can be empty for now but we’ll import and use it in the root App component.

Example: src/App.svelte
<script>
  import Child from './components/Child.svelte'
</script>

<Child />

Step 1: Add a custom attribute on the component instance tag

To create a prop, we add an attribute to the child component’s instance in the parent’s markup block.

Syntax: parent prop attribute
<child-component propName="propValue" />

As an example, we’ll create 4 instances of our Child component and add a name prop with a different value for each.

Example: src/App.svelte
<script>
  import Child from './components/Child.svelte'
</script>

<Child name="John" />
<Child name="Jane" />
<Child name="Jack" />
<Child name="Jill" />

That’s all we need to send the data to child component.

Step 2: Register the prop in the child component

To register the prop, we declare a variable in the child component with the same name as the prop and export it in the script block.

Syntax: export prop
<script>
  export let propName
</script>

As an example, let’s register the name prop in our Child component.

Example: src/components/Child.svelte
<script>
  export let name
</script>

That’s all we need to register the prop.

Step 3: Use the prop in the child component

We can now use the prop in the same way we use other variables, for instance databinding.

Syntax: use prop
<script>
  export let propName
</script>

<p>{propName}</p>

As an example, let’s bind the name prop to a greeting message in the child’s markup.

Example: src/components/Child.svelte
<script>
  export let name
</script>

<p>Hello {name}</p>

If we save everything and run the example in the browser, we should see 4 greeting messages with the different names.

Output:
Hello John

Hello Jane

Hello Jack

Hello Jill

How to add default values to props in Svelte

Svelte allows us to specify a default value for a prop in case the prop isn’t defined on the component instance.

To do that, we simply add a value to the exported variable definition in the child component.

Syntax: default prop value
<script>
  export let propName = defaultValue
</script>

As an example, let’s add a default value to the name prop in our Child component.

Example: src/components/Child.svelte
<script>
  export let name = 'Unknown'
</script>

<p>Hello {name}</p>

Then we’ll add another instance of Child in the root App component, but this time we don’t include the name attribute.

Example: src/App.svelte
<script>
  import Child from './components/Child.svelte'
</script>

<Child name="John" />
<Child name="Jane" />
<Child name="Jack" />
<Child name="Jill" />
<Child />

If we run the example in the browser, we should see 4 greeting messages with names and one with the default value we specified.

Output:
Hello John

Hello Jane

Hello Jack

Hello Jill

Hello Unknown

How to use multiple props on a single component instance in Svelte

Svelte allows us to use as many props on a component as we need. All we need to do is just add more props, separated by a space.

Syntax: multiple props
<child-component
  prop_1="value_1"
  prop_2="value_2"
/>

To demonstrate, let’s add a lastName prop to the root App component of our previous example. We’ll also simplify the example and only use two child component instances.

Example: src/App.svelte
<script>
  import Child from './components/Child.svelte'
</script>

<Child name="John" lastName="Doe" />
<Child name="Jane" lastName="Roe" />

Then, we’ll register and use the prop in Child in the greeting message.

Example: src/components/Child.svelte
<script>
  export let name = 'Unknown'
  export let lastName = 'Unknown'
</script>

<p>Hello {name} {lastName}</p>

If we save and take a look at the browser, we see the new lastName prop added to the greeting messages.

Output:
Hello John Doe

Hello Jane Roe

How to use dynamic values with props in Svelte

So far we’ve been hardcoding our values. Most of the time though, the values will come from some other source, like an input, database or computation.

In that case, all we need to do is bind the dynamic value to the prop’s value.

Syntax: dynamic value
<script>
  const dynamicValue = value
</script>

<child-component propName={dynamicValue} />

As an example, let’s take the name from the user with input binding . We’ll also simplify the example by using only one Child instance with only the name prop.

Example: src/App.svelte
<script>
  import Child from './components/Child.svelte'

  let dynamicName = ''
</script>

<label for="name">Name: { dynamicName }</label>
<input type="text" id="name" bind:value={dynamicName}>

<Child name={dynamicName} />

And because we simplify it in the parent, we’ll need to remove the lastName in the child.

Example: src/components/Child.svelte
<script>
  export let name
</script>

<p>Hello {name}</p>

If we run the example and enter a name in the browser, it will update the greeting message.

The shorthand syntax for dynamic props in Svelte

If a prop name and a dynamic value name is the same, we can use a shorthand and just bind the value. Svelte will understand that we want to use it as a prop name.

Syntax: prop shorthand
<script>
  const dynamicValue = value
</script>

<!-- same prop and value name -->
<child-component dynamicValue="{dynamicValue}" />

<!-- can use the shorthand -->
<child-component {dynamicValue} />

As an example, let’s change our dynamicName constant into name in the root App component.

Because it’s now the same as the prop, we can use the shorthand.

Example: src/App.svelte
<script>
  import Child from './components/Child.svelte'

  let name = ''
</script>

<label for="name">Name: { name }</label>
<input type="text" id="name" bind:value={name}>

<Child {name} />

If we run the example in the browser and enter a name, the greeting message will still update as expected.

How to spread object in props in Svelte

When our dynamic prop values come from an external source, it will most likely be in an object.

While it’s perfectly valid to access object properties with dot notation, there is an easier way.

Syntax: dot notation
<script>
  const object {
    key_1: value_1,
    key_2: value_2
  }
</script>

<child-component prop="object.key_1" />

Svelte allows us to spread an object into a component instance and use the object keys as props.

Syntax: spread props
<script>
  const object {
    key_1: value_1,
    key_2: value_2
  }
</script>

<child-component {...object} />

As an example, let’s change our name variable to be an object with name as its property. Then we’ll spread the object in the component instance.

Example: src/App.svelte
<script>
  import Child from './components/Child.svelte'

  const user = {
    name: ''
  }
</script>

<label for="name">Name: { user.name }</label>
<input type="text" id="name" bind:value="{ user.name }">

<!-- spread "user" object as props -->
<Child {...user} />

If we run the example in the browser, everything should still work the same.

tip Our example only uses a single prop so it may not seem very useful at the moment. But when you have 10 or more props, it makes a big difference.