Search code examples
dynamicsvelteappendchildsvelte-component

Adding a svelte component to DOM at runtime?


Adding a svelte component (Button) statically in the body section works. Adding the Button via appendChild does not?

Details:

Imagine a database table. For each row I add a line into my HTML body.

How could I add a svelte component (Button.svelte) to each row, too?

The problem: Standard HTML gets appended, but my svelte Button does not. (Probably because svelte needs to render at compile time.)

For example in +page.svelte:

const e = document.getElementById('my_div_container');
if(e)
{
    const p = document.createElement("p");
    const txt = document.createTextNode("test node");
    p.appendChild(txt);
    e.appendChild(p); // <-- ok, gets displayed
    const b = document.createElement("Button");
    e.appendChild(b); // <-- NOT displayed
}

Example lib/Button.svelte:

<script>
    function on_click()
    {
        console.log('clicked');
    }
</script>
<button on:click={() => on_click()}>Click</button>

FYI: Statically adding a button to the HTML body works of course:

<p>Some text</p>
<Button />

Solution

  • You can either build components as custom elements, then they can be created with createElement or just use the client component API. For that, you need to import the component and construct it, setting the target to the element you want to add it to:

    new Button({ target: e })