Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a Svelte component be embedded in a non-Svelte app?

I work in a group that has several projects, and each one is written in a different framework. We would like to have some self-contained widgets whose behavior and appearance are standard, but can be used in any of the systems. I thought Svelte sounded like a good option, because it doesn't require adding a framework on the front end. But I can't find anything that says Svelte is usable within other systems; it has to be an all-Svelte app to have Svelte components.

Is that correct? Or is there some way to embed a Svelte component into another system?

like image 623
Roy J Avatar asked Apr 09 '20 23:04

Roy J


People also ask

Is Svelte component based?

In Svelte, an application is composed from one or more components. A component is a reusable, self-contained block of code that encapsulates HTML, CSS, and JavaScript that belong together, written into a . svelte file.

How do you pass component as prop in Svelte?

The solution. To pass Svelte components dynamically down to a child component you have to use Svelte's <svelte:component> directive. <svelte:component> accepts a property called this . If the property this has a component attach to it than it will render the given Svelte component.

How do I add components to Svelte?

Click Event. Above we simply have added one event, click , and we can add events to any DOM element by using the on:event={functionName} syntax. Above, we've added on:click={addToCounter} to signify that we will run addToCounter() anytime someone clicks the button.


2 Answers

You can include a Svelte component anywhere as soon as you have the reference to the DOM element you want to append your Svelte component.

const container = document.querySelector('.container');

//MyComponent is the compiled component
new MyComponent({
  target : container
});

See the Svelte docs: https://svelte.dev/docs#run-time-client-side-component-api

But then you have some limitation on how you can handle the state if you have multiple components included like that.

like image 175
krampstudio Avatar answered Oct 20 '22 18:10

krampstudio


If you want even wider compatibility and just include the component with a script tag, you can use the document.currentScript property and compile the Javascript into standalone script with rollup.js or webpack:

import MyComponent from './MyComponent.svelte';

var div = document.createElement('DIV');
var script = document.currentScript;
script.parentNode.insertBefore(div, script);

const myComponent = new MyComponent({
    target: div,
    props: { propname: 'some value' },
});

You can compile a nice package with rollup if you have rollup-plugin-svelte and @rollup/plugin-node-resolve packages installed into your project. Below is a suitable rollup.config.js for this, added further notes into comments:

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';

export default {
    input: 'embed.js',
    output: {
        format: 'iife',
        file: 'dist.js',
    sourcemap: false,
    },
    plugins: [
        svelte({ emitCss: false, }),
        resolve({ browser: true, dedupe: ['svelte'] }),
    ],
}
like image 25
jokkebk Avatar answered Oct 20 '22 18:10

jokkebk