Installation
Install thelivecodes package:
npm install livecodes
Basic Usage
Use thecreatePlayground function in Svelte’s lifecycle:
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
let container;
let playground;
onMount(async () => {
playground = await createPlayground(container, {
config: {
markup: {
language: 'html',
content: '<h1>Hello from Svelte!</h1>',
},
},
});
});
</script>
<div bind:this={container}></div>
Complete Example
<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
let container;
let playground;
const config = {
markup: {
language: 'html',
content: '<h1>Hello, World!</h1>',
},
style: {
language: 'css',
content: 'h1 { color: #ff3e00; font-family: sans-serif; }',
},
script: {
language: 'javascript',
content: 'console.log("Hello from LiveCodes!");',
},
};
onMount(async () => {
playground = await createPlayground(container, { config });
});
onDestroy(() => {
playground?.destroy();
});
</script>
<div bind:this={container} class="playground" />
<style>
.playground {
height: 500px;
border: 1px solid #ddd;
border-radius: 8px;
}
</style>
With Template
<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
export let template = 'svelte';
let container;
let playground;
onMount(async () => {
playground = await createPlayground(container, { template });
});
onDestroy(() => {
playground?.destroy();
});
</script>
<div bind:this={container} class="playground" />
<style>
.playground {
height: 600px;
}
</style>
Interactive Controls
<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
let container;
let playground;
const handleRun = async () => {
await playground?.run();
};
const handleFormat = async () => {
await playground?.format();
};
const handleGetCode = async () => {
const code = await playground?.getCode();
console.log('Current code:', code);
};
onMount(async () => {
playground = await createPlayground(container, {
template: 'javascript',
});
});
onDestroy(() => {
playground?.destroy();
});
</script>
<div class="container">
<div class="controls">
<button on:click={handleRun}>Run</button>
<button on:click={handleFormat}>Format</button>
<button on:click={handleGetCode}>Get Code</button>
</div>
<div bind:this={container} class="playground" />
</div>
<style>
.controls {
margin-bottom: 1rem;
display: flex;
gap: 0.5rem;
}
button {
padding: 0.5rem 1rem;
border: 1px solid #ff3e00;
background: white;
color: #ff3e00;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #ff3e00;
color: white;
}
.playground {
height: 400px;
}
</style>
Watching Events
<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
let container;
let playground;
let logs = [];
let watchers = [];
onMount(async () => {
playground = await createPlayground(container, {
template: 'javascript',
});
// Watch console output
const consoleWatcher = playground.watch('console', ({ method, args }) => {
logs = [...logs, { method, args, timestamp: Date.now() }];
});
// Watch code changes
const codeWatcher = playground.watch('code', ({ code }) => {
console.log('Code changed:', code.script.content);
});
watchers = [consoleWatcher, codeWatcher];
});
onDestroy(() => {
watchers.forEach(w => w.remove());
playground?.destroy();
});
</script>
<div>
<div bind:this={container} class="playground" />
<div class="console-output">
<h3>Console Output:</h3>
<ul>
{#each logs as log (log.timestamp)}
<li>{log.method}: {JSON.stringify(log.args)}</li>
{/each}
</ul>
</div>
</div>
<style>
.playground {
height: 300px;
margin-bottom: 1rem;
}
.console-output {
padding: 1rem;
background: #f5f5f5;
border-radius: 4px;
}
</style>
Reactive Configuration
<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
let container;
let playground;
let language = 'javascript';
let code = 'console.log("Hello!");';
$: if (playground) {
updateConfig();
}
const updateConfig = async () => {
if (!playground) return;
await playground.setConfig({
script: {
language,
content: code,
},
});
};
onMount(async () => {
playground = await createPlayground(container, {
config: {
script: { language, content: code },
},
});
});
onDestroy(() => {
playground?.destroy();
});
</script>
<div class="container">
<div class="controls">
<select bind:value={language}>
<option value="javascript">JavaScript</option>
<option value="typescript">TypeScript</option>
<option value="python">Python</option>
</select>
<textarea bind:value={code} rows="3" />
</div>
<div bind:this={container} class="playground" />
</div>
<style>
.controls {
margin-bottom: 1rem;
}
textarea {
width: 100%;
padding: 0.5rem;
font-family: monospace;
margin-top: 0.5rem;
}
.playground {
height: 400px;
}
</style>
Creating a Reusable Component
Create a reusableLiveCodes.svelte component:
<!-- LiveCodes.svelte -->
<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
export let config = undefined;
export let template = undefined;
export let loading = 'lazy';
export let height = '500px';
export let onReady = undefined;
let container;
let playground;
onMount(async () => {
playground = await createPlayground(container, {
config,
template,
loading,
});
if (onReady) {
onReady(playground);
}
});
onDestroy(() => {
playground?.destroy();
});
</script>
<div
bind:this={container}
class="livecodes-container"
style="height: {height}"
/>
<style>
.livecodes-container {
width: 100%;
border: 1px solid #ddd;
border-radius: 8px;
}
</style>
<script>
import LiveCodes from './LiveCodes.svelte';
const config = {
markup: {
language: 'html',
content: '<h1>Reusable Component</h1>',
},
};
const handleReady = (playground) => {
console.log('Playground is ready!', playground);
};
</script>
<LiveCodes
{config}
height="600px"
onReady={handleReady}
/>
TypeScript Support
For TypeScript, create a.svelte file with TypeScript in the script tag:
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
import type { Playground, Config } from 'livecodes';
let container: HTMLDivElement;
let playground: Playground | undefined;
const config: Partial<Config> = {
markup: {
language: 'html',
content: '<h1>TypeScript Support</h1>',
},
};
onMount(async () => {
playground = await createPlayground(container, { config });
});
onDestroy(() => {
playground?.destroy();
});
</script>
<div bind:this={container} class="playground" />
<style>
.playground {
height: 500px;
}
</style>
SvelteKit Integration
For SvelteKit, ensure the SDK loads only on the client:<script>
import { onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
let container;
let playground;
onMount(async () => {
if (browser) {
const { createPlayground } = await import('livecodes');
playground = await createPlayground(container, {
template: 'svelte',
});
}
});
onDestroy(() => {
playground?.destroy();
});
</script>
<div bind:this={container} class="playground" />
<style>
.playground {
height: 600px;
}
</style>
<!-- +page.svelte -->
<script>
import Playground from './Playground.svelte';
</script>
{#if browser}
<Playground />
{/if}
Props Pattern
Create a component that accepts props:<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
export let appUrl = undefined;
export let config = undefined;
export let template = undefined;
export let loading = 'lazy';
export let headless = false;
export let height = '500px';
let container;
let playground;
$: options = {
appUrl,
config,
template,
loading,
headless,
};
onMount(async () => {
playground = await createPlayground(container, options);
});
onDestroy(() => {
playground?.destroy();
});
</script>
<div
bind:this={container}
style="height: {height}"
class="playground"
/>
Best Practices
-
Always destroy: Call
playground.destroy()inonDestroyto clean up. - Use bind:this: Bind the container element for direct reference.
- Check browser environment: In SvelteKit, ensure code runs only on client.
-
Handle async properly: Use
awaitwhen calling playground methods. -
Remove watchers: Clean up event watchers in
onDestroy.
Common Patterns
Loading State
<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
let container;
let playground;
let loading = true;
onMount(async () => {
playground = await createPlayground(container, {
template: 'svelte',
});
loading = false;
});
onDestroy(() => {
playground?.destroy();
});
</script>
{#if loading}
<div class="loading">Loading playground...</div>
{/if}
<div bind:this={container} class="playground" class:hidden={loading} />
<style>
.hidden {
display: none;
}
.loading {
height: 500px;
display: flex;
align-items: center;
justify-content: center;
background: #f5f5f5;
}
</style>
Error Handling
<script>
import { onMount, onDestroy } from 'svelte';
import { createPlayground } from 'livecodes';
let container;
let playground;
let error = null;
onMount(async () => {
try {
playground = await createPlayground(container, {
template: 'svelte',
});
} catch (err) {
error = err.message;
console.error('Failed to create playground:', err);
}
});
onDestroy(() => {
playground?.destroy();
});
</script>
{#if error}
<div class="error">
Error: {error}
</div>
{:else}
<div bind:this={container} class="playground" />
{/if}
Next Steps
Methods
Explore all available SDK methods
Events
Learn about the event system
Types
Browse TypeScript type definitions
Getting Started
Back to getting started guide