DEV Community

Cover image for Tutorial: Dynamic Svelte Components
CodeCadim by Brahim Hamdouni
CodeCadim by Brahim Hamdouni

Posted on • Originally published at barim.us

Tutorial: Dynamic Svelte Components

Svelte offers remarkable flexibility for creating dynamic components.
In this tutorial, we'll explore how to instantiate components on the fly
and pass properties to them in an elegant and efficient manner.

Basics of Dynamic Components

<script>
  import Foo from "./Foo.svelte";
  import Bar from "./Bar.svelte";
  let actual = Foo;
</script>

<svelte:component this={actual} on:click={()=>actual=Bar} />
Enter fullscreen mode Exit fullscreen mode

In this simple example, we import two components: Foo and Bar.

We create a variable actual where we'll place the current component, in this case Foo.

Svelte offers a special <svelte:component> tag that allows creating components on the fly.

We specify in the this property which component to display, in our example, actual.

For demonstration, we add an on:click event to change the component to Bar by simply modifying the actual variable.

Svelte takes care of displaying the component by substituting Bar for Foo.

Passing Parameters (props)

A key point is the ability to pass parameters to dynamic components. For a classic component, you can write:

<Foo age=22 />
Enter fullscreen mode Exit fullscreen mode

We assign the value 22 to the age property.

For a dynamic component, it's the same:

<svelte:component this={Foo} age=22 />
Enter fullscreen mode Exit fullscreen mode

But let's imagine our second component Bar accepts 2 parameters:

<Bar age=572 name="Da Vinci" />
Enter fullscreen mode Exit fullscreen mode

Our dynamic component should be written as:

<svelte:component this={Bar} age=572 name="Da Vinci" />
Enter fullscreen mode Exit fullscreen mode

And there, we have a problem. How to manage them in the dynamic component while passing the right number of parameters?

My technique involves encapsulating the component with its properties in an object and using the spread operator {...props}.

For example, for the Foo component, I would write an object FooCmp:

<script>
    let FooCmp = {
        cmp: Foo,
        props: {
            age: 42
        }
    }
    let actual = FooCmp;
</script>

<svelte:component
    this={actual.cmp}
    {...actual.props}
/>
Enter fullscreen mode Exit fullscreen mode

Here's the complete example, using the 2 components and a
flip function to interchange them.

App.svelte

<script>
  import Foo from "./Foo.svelte";
  import Bar from "./Bar.svelte";
  let FooCmp = {
    cmp: Foo,
    props: {
      age: 42
    }
  };
  let BarCmp = {
    cmp: Bar,
    props: {
      age: 572,
      name: "Da Vinci"
    }
  };
  let actual = FooCmp;
  let flip = () => actual = actual.cmp == Foo ? BarCmp : FooCmp;
</script>

<svelte:component
    this={actual.cmp}
    on:click={flip}
    {...actual.props}
/>
Enter fullscreen mode Exit fullscreen mode

Each imported component will display its properties in a button and activate the on:click event.

Foo.svelte

<script>
    export let age = 0;
</script>

<button on:click>Foo {age}</button>
Enter fullscreen mode Exit fullscreen mode

Bar.svelte

<script>
    export let name = "";
    export let age = 0;
</script>

<button on:click>Bar {name} {age}</button>
Enter fullscreen mode Exit fullscreen mode

Note that we only pass through the on:click event as it is not processed here, but at the level of the parent, the dynamic component.

Conclusion

You can easily instantiate and manipulate components on the fly with <svelte:component>. Svelte offers a simple and powerful approach to creating dynamic components.

And JavaScript provides us with all the tools to work around the problem of different numbers of props per component.

Don't hesitate to experiment and adapt this approach to your own needs!

Top comments (0)