Svelte is a framework for building user interfaces on the web. It uses a compiler to turn declarative components written in HTML, CSS and JavaScript.
Usage
Svelte components can be used as documented in the docs. See below for usage.
Demo
show code
import { createPlayground } from 'livecodes';
const options = {
"template": "svelte"
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"template": "svelte"
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"template": "svelte"
};
return (<LiveCodes {...options}></LiveCodes>);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"template": "svelte"
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
let options = $state({
"template": "svelte"
});
let container = $state(null);
onMount(() => {
createPlayground(container, options);
});
</script>
<div bind:this="{container}"></div>
CSS Frameworks
CSS Frameworks supported in LiveCodes (e.g. Tailwind CSS, UnoCSS, WindiCSS) can detect class names added in Svelte components.
Make sure that the required utility is enabled (from style editor menu or in processors
property of configuration object).
See example below.
Please note that the style block can use any of the supported languages that compile to CSS (e.g. SCSS, Stylus, etc),
but currently is not processed by CSS processors (e.g. Tailwind CSS, Autoprefixer, etc).
See limitations.
Languages and Pre-Processors
Many of the languages supported in LiveCodes can be used. The value of lang
attribute can be the language name (specified in its documentation page) or any of its aliases (extensions).
You may wrap the markup in a template
element if you want to specify the lang
attribute.
Module Imports
npm modules can be imported as described in the section about module resolution, including bare module imports and importing from different CDNs. Stylesheets imported in the script
block are added as <link rel="stylesheet">
tags in the page head
.
Example:
Module imports can be customized using import maps as described in module resolution documentations.
Multiple Components
Svelte is supported in both markup and script editors.
This allows having a component in the markup editor that imports (and passes props to) a component in the script editor. The opposite is not supported.
This can be done using relative import of a file name in the same directory. Any file name will resolve to the component in the script editor,
e.g. ./script.svelte
, ./Component.svelte
, ./Counter.svelte
, etc.
show code
import { createPlayground } from 'livecodes';
const options = {
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n"
},
"processors": [
"tailwindcss"
]
}
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n"
},
"processors": [
"tailwindcss"
]
}
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n"
},
"processors": [
"tailwindcss"
]
}
};
return (<LiveCodes {...options}></LiveCodes>);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n"
},
"processors": [
"tailwindcss"
]
}
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
let options = $state({
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n"
},
"processors": [
"tailwindcss"
]
}
});
let container = $state(null);
onMount(() => {
createPlayground(container, options);
});
</script>
<div bind:this="{container}"></div>
Please note that LiveCodes does not have the concept of a file system. However, you can configure editor options like title
, order
and hideTitle
to simulate multiple files, change editor order or even hide editors.
Example:
show code
import { createPlayground } from 'livecodes';
const options = {
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n",
"title": "App.svelte"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n",
"title": "Counter.svelte"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n",
"title": "styles.css",
"order": 3
},
"processors": [
"tailwindcss"
]
}
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n",
"title": "App.svelte"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n",
"title": "Counter.svelte"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n",
"title": "styles.css",
"order": 3
},
"processors": [
"tailwindcss"
]
}
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n",
"title": "App.svelte"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n",
"title": "Counter.svelte"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n",
"title": "styles.css",
"order": 3
},
"processors": [
"tailwindcss"
]
}
};
return (<LiveCodes {...options}></LiveCodes>);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n",
"title": "App.svelte"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n",
"title": "Counter.svelte"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n",
"title": "styles.css",
"order": 3
},
"processors": [
"tailwindcss"
]
}
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
let options = $state({
"config": {
"markup": {
"language": "svelte",
"content": "<script lang=\"ts\">\nimport Counter from './Counter.svelte';\n</script>\n\n<Counter start=\"5\" />\n",
"title": "App.svelte"
},
"script": {
"language": "svelte",
"content": "<script lang=\"ts\">\n let { start } = $props();\n let count = $state(start);\n</script>\n\n<div class=\"mt-8 text-center\">\n <span class=\"text-3xl font-bold\">{count}</span>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count--} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">-</button>\n <button on:click={() => count++} class=\"text-md font-medium bg-gray-500 hover:bg-gray-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">+</button>\n</div>\n<div class=\"mt-4 space-x-4 text-center\">\n <button on:click={() => count = start} class=\"text-md font-medium bg-red-500 hover:bg-red-600 transition py-1 px-4 text-white rounded drop-shadow-xl\">Reset</button>\n</div>\n",
"title": "Counter.svelte"
},
"style": {
"language": "css",
"content": "@import \"tailwindcss\";\n",
"title": "styles.css",
"order": 3
},
"processors": [
"tailwindcss"
]
}
});
let container = $state(null);
onMount(() => {
createPlayground(container, options);
});
</script>
<div bind:this="{container}"></div>
When both markup and script editors use Svelte, the component in the markup editor is used as the main component rendered in the root element.
To render the component in the script editor, it has to be imported and used by the main component.
Importing External Components
External Svelte components can be imported. The import URL has to be an absolute URL ending with .svelte
extension. Any bare or relative imports in the imported files are resolved and compiled recursively.
Example:
<script>
import Counter from 'https://raw.githubusercontent.com/user/repo/main/src/Counter.svelte';
</script>
<Counter />
Root Element
To mount the application instance to a specific DOM element use "livecodes-app"
as the element id
in the HTML. Otherwise, if that element is not found, a new div
element is added to document.body
and is used to mount the instance.
Example:
show code
import { createPlayground } from 'livecodes';
const options = {
"config": {
"markup": {
"language": "html",
"content": "<h1>Custom Root Element</h1>\n<div id=\"livecodes-app\"></div>\n<p>...other page content</p>\n"
},
"script": {
"language": "svelte",
"content": "<script>\n let name = $state('Svelte');\n</script>\n\n<div>I'm a {name} component</div>\n"
}
}
};
createPlayground('#container', options);
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
"config": {
"markup": {
"language": "html",
"content": "<h1>Custom Root Element</h1>\n<div id=\"livecodes-app\"></div>\n<p>...other page content</p>\n"
},
"script": {
"language": "svelte",
"content": "<script>\n let name = $state('Svelte');\n</script>\n\n<div>I'm a {name} component</div>\n"
}
}
};
createPlayground('#container', options);
import LiveCodes from 'livecodes/react';
export default function App() {
const options = {
"config": {
"markup": {
"language": "html",
"content": "<h1>Custom Root Element</h1>\n<div id=\"livecodes-app\"></div>\n<p>...other page content</p>\n"
},
"script": {
"language": "svelte",
"content": "<script>\n let name = $state('Svelte');\n</script>\n\n<div>I'm a {name} component</div>\n"
}
}
};
return (<LiveCodes {...options}></LiveCodes>);
}
<script setup>
import LiveCodes from "livecodes/vue";
const options = {
"config": {
"markup": {
"language": "html",
"content": "<h1>Custom Root Element</h1>\n<div id=\"livecodes-app\"></div>\n<p>...other page content</p>\n"
},
"script": {
"language": "svelte",
"content": "<script>\n let name = $state('Svelte');\n</script>\n\n<div>I'm a {name} component</div>\n"
}
}
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
let options = $state({
"config": {
"markup": {
"language": "html",
"content": "<h1>Custom Root Element</h1>\n<div id=\"livecodes-app\"></div>\n<p>...other page content</p>\n"
},
"script": {
"language": "svelte",
"content": "<script>\n let name = $state('Svelte');\n</script>\n\n<div>I'm a {name} component</div>\n"
}
}
});
let container = $state(null);
onMount(() => {
createPlayground(container, options);
});
</script>
<div bind:this="{container}"></div>
Language Info
Name
svelte
Extensions
.svelte
Editor
script
, markup
Compiler
The official Svelte compiler.
Version
svelte
: v5.12.0
Using Prettier.
Limitations
Code in style blocks are not currently processed by enabled CSS processors. This is already discouraged by Tailwind CSS.
PRs are welcome.
Starter Template
https://livecodes.io/?template=svelte
Links