Code and Life

Programming, electronics and other cool tech stuff

Easy-to-Embed Svelte Components As Script Tag with Rollup

After Angular, React.js and Vue, svelte is the new and cool kid on the block. I have to admit, the compile-to-plain-javascript philosophy is nice, and what is especially cool is the fact that with Rollup.js you can easily bundle a svelte app into easy-to-embed component.

I wanted to make a simple embeddable Svelte component for a friend of mine, that would be as simple as possible to include in a blog post, web site or similar with just:

<script src="https://mydomain.com/myscript.js"></script>

The script should ideally just put the component in the same place. Turns out this is really easy with Svelte. Let's dive in!

Setting up Svelte

You may want to read more about rollup-plugin-svelte and Making an app from excellent Svelte tutorial to get more familiar with the tools used here, as I'll only cover the bare essentials.

First you need to install the necessary plugins. We'll start with Rollup and install it globally so you can just use rollup command to do things. If you want, you can also install rollup locally.

user@server:~$ sudo npm install --global rollup
user@server:~$ rollup -v
rollup v2.40.0

I initially got an error saying something about imports and after a bit of googling found out that my Ubuntu version of node was very old (node -v outputted 8.x.x when 10+ was needed) – if you encounter the same issue, upgrade to a newer node (nvm is a great too to do this).

Next make a product directory and install svelte and rollup-plugin-svelte:

user@server:~$ mkdir embed-svelte
user@server:~$ cd embed-svelte/
user@server:~/embed-svelte$ npm init

[answering to npm prompts]

user@server:~/embed-svelte$ npm install --save-dev svelte
user@server:~/embed-svelte$ npm install --save-dev rollup-plugin-svelte
user@server:~/embed-svelte$ npm install --save-dev @rollup/plugin-node-resolve

Simple Svelte component

We'll go really barebones with this tutorial, just a simple heading and a paragraph. Create a Svelte component Embed.svelte:

<script>
export let name; // from props
</script>

<h1>Hello, {name}!</h1>

<p>This component was brought to you by <a href="https://codeandlife.com/">Code
  &amp; Life</a>.</p>

Then we'll need a simple .js script to import that our mini-component and inject it to the DOM of whatever page has included the resulting script. Let's call this embed.js:

import Embed from './Embed.svelte';

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

const embed = new Embed({
	target: div,
	props: { name: 'Svelte component' },
});

The code uses document.currentScript that points to current script element and creates a div element before the script, and renders our Svelte component into it. Cool!

Rolling it up with Rollup.js

We can now make a simple rollup.config.js to generate the final script:

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'] }),
	],
}

The rollup-plugin-svelte makes rollup understand .svelte files and the @rollup/plugin-node-resolve is needed so any imports in our code are rolled into the dist.js specified as output. See details here.

Once the configuration is done, generating our dist.js is easy as pie:

user@server:~/embed-svelte$ rollup -c rollup.config.js

embed.js → dist.js...
created dist.js in 157ms

Testing if it works

Let's make a simple demo.html page to try it out!

<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Demo page</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<body>

  <h1>Svelte embedding demo</h1>
  
  <p>Below, we have inserted a <code>script</code> tag that should
  renter a Svelte component upon loading this page.</p>

  <script src="dist.js"></script>

  <p>This text will come after the embedded content.</p>
</body>
</html>

Once you have generated dist.js and put the demo page to same folder, fire up the browser and you should see something like this:

demo page content

Wrapping it up

Congratulations! You can now use Svelte components like a true ninja. With a little coding you could make an interactive calculator application to embed on a web page, or perhaps some other cool widget to fetch some data with AJAX and display it on your blog.

You can find all code for this tutorial in my embed-svelte Github repo.

comments