prototype
MAmattpocock/skills288k近 7 天新增 10,178 个 star
Use SDK with React, Vue, Svelte, Solid, Preact, and Web Components. sdkReady callback pattern, reactive props, and framework-specific setup. Load this skill when embedding LiveCodes in a framework application.
This skill builds on sdk-embedding and sdk-methods. Read them first for foundational concepts about createPlayground, SDK methods, and configuration.
LiveCodes provides framework-specific components that wrap the core SDK. Each wrapper handles lifecycle, reactivity, and props.
import LiveCodes from 'livecodes/react';
// Basic usage
function App() {
return <LiveCodes template="react" />;
}
// With config
function App() {
const config = {
markup: { language: 'markdown', content: '# Hello World' },
};
return <LiveCodes config={config} height="400px" />;
}
// Access SDK methods via sdkReady
function App() {
const [playground, setPlayground] = useState(null);
const handleRun = async () => {
await playground?.run();
};
return (
<>
<LiveCodes
template="react"
sdkReady={setPlayground}
/>
<button onClick={handleRun}>Run</button>
</>
);
}
// TypeScript
import LiveCodes, { type Props } from 'livecodes/react';
const options: Props = {
config: { /* ... */ },
height: '500px',
};
export default () => <LiveCodes {...options} />;
| Prop | Type | Description |
|---|---|---|
| All EmbedOptions | — | Pass EmbedOptions as props |
className | string | Container class name |
height | string | Container height |
style | object | Container styles |
sdkReady | (sdk: Playground) => void | Callback with SDK instance |
function App() {
const [config, setConfig] = useState({
markup: { language: 'html', content: '<h1>Hello</h1>' },
});
// Changing config uses setConfig() - no full reload
const switchToMarkdown = () => {
setConfig({
markup: { language: 'markdown', content: '# Hello' },
});
};
// Changing other props causes full reload
// <LiveCodes template={template} /> // changing template reloads
return (
<>
<LiveCodes config={config} />
<button onClick={switchToMarkdown}>Switch to Markdown</button>
</>
);
}
<script setup>
import LiveCodes from 'livecodes/vue';
const config = {
markup: { language: 'markdown', content: '# Hello World' },
};
let playground;
const onReady = (sdk) => {
playground = sdk;
};
const run = async () => {
await playground?.run();
};
</script>
<template>
<LiveCodes :config="config" @sdk-ready="onReady" />
<button @click="run">Run</button>
</template>
<!-- With TypeScript -->
<script setup lang="ts">
import LiveCodes, { type Props } from 'livecodes/vue';
import type { Playground } from 'livecodes';
const options: Props = {
config: {
/* ... */
},
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
| Prop | Type | Description |
|---|---|---|
| All EmbedOptions | — | Pass EmbedOptions as props |
height | string | Container height |
| Event | Payload |
|---|---|
@sdk-ready | (sdk: Playground) => void |
<script setup>
import { ref } from 'vue';
import LiveCodes from 'livecodes/vue';
const config = ref({
markup: { language: 'html', content: '<h1>Hello</h1>' },
});
// Uses setConfig() - no reload
const switchToMarkdown = () => {
config.value = {
markup: { language: 'markdown', content: '# Hello' },
};
};
</script>
<template>
<LiveCodes :config="config" />
<button @click="switchToMarkdown">Switch</button>
</template>
<script>
import LiveCodes from 'livecodes/svelte';
let playground;
const config = {
markup: { language: 'markdown', content: '# Hello World' },
};
function onReady(sdk) {
playground = sdk;
}
async function run() {
await playground?.run();
}
</script>
<LiveCodes {config} on:sdkReady={onReady} />
<button on:click={run}>Run</button>
import LiveCodes from 'livecodes/solid';
import { createSignal } from 'solid-js';
function App() {
const [playground, setPlayground] = createSignal(null);
const config = {
markup: { language: 'markdown', content: '# Hello World' },
};
const handleRun = async () => {
await playground()?.run();
};
return (
<>
<LiveCodes config={config} sdkReady={setPlayground} />
<button onClick={handleRun}>Run</button>
</>
);
}
import LiveCodes from 'livecodes/preact';
import { useState } from 'preact/hooks';
function App() {
const [playground, setPlayground] = useState(null);
const handleRun = async () => {
await playground?.run();
};
return (
<>
<LiveCodes template="react" sdkReady={setPlayground} />
<button onClick={handleRun}>Run</button>
</>
);
}
<script src="https://cdn.jsdelivr.net/npm/livecodes/web-components.js"></script>
<!-- Basic usage -->
<live-codes template="react"></live-codes>
<!-- With config property -->
<live-codes height="400px"></live-codes>
<script>
const playground = document.querySelector('live-codes');
playground.config = {
markup: { language: 'markdown', content: '# Hello' },
};
</script>
The web component supports providing code declaratively as child elements inside a wrapper <template>. This avoids JavaScript string escaping and enables IDE syntax highlighting.
The outer <template> makes inner <style> and <script> elements inert (no side effects on the embedding page).
<live-codes height="400px">
<template>
<template lang="html">
<h1>Hello World</h1>
<p>Welcome to <strong>LiveCodes</strong></p>
</template>
<style lang="scss">
body {
font-family: sans-serif;
h1 {
color: royalblue;
}
}
</style>
<script lang="ts">
console.log('Hello from TypeScript!');
</script>
</template>
</live-codes>
If lang is omitted, defaults are html, css, and javascript.
Use the active boolean attribute to set the initially focused editor:
<live-codes>
<template>
<template lang="html"><h1>Hello</h1></template>
<script lang="ts" active>
console.log('focused');
</script>
</template>
</live-codes>
Use config and params HTML attributes as JSON strings for non-code settings:
<live-codes config='{"processors": ["tailwindcss"]}' params='{"console": "open"}'>
<template>
<template lang="html"><h1 class="text-3xl">Hello</h1></template>
</template>
</live-codes>
When combining children, config attribute, and config property:
config property (highest — explicit programmatic override)config attribute (lowest — inline JSON settings)Same for params: attribute is merged with property, property wins for overlapping keys.
Children content is reactive. Changing content inside the wrapper <template> programmatically triggers setConfig():
<live-codes id="demo">
<template>
<style lang="css">
h1 {
color: blue;
}
</style>
</template>
</live-codes>
<script>
function changeColor() {
const wrapper = document.querySelector('#demo > template');
wrapper.content.querySelector('style').textContent = 'h1 { color: red; }';
// MutationObserver detects this → setConfig() called
}
</script>
Wrong (React):
function App() {
// No way to get SDK reference
return <LiveCodes template="react" />;
}
function handleRun() {
// Where's playground? Can't access SDK methods
playground.run(); // Error: playground is undefined
}
Correct (React):
function App() {
const [playground, setPlayground] = useState(null);
const handleRun = async () => {
await playground?.run();
};
return (
<>
<LiveCodes template="react" sdkReady={setPlayground} />
<button onClick={handleRun}>Run</button>
</>
);
}
Correct (Vue):
<script setup>
import LiveCodes from 'livecodes/vue';
import { ref } from 'vue';
const playground = ref(null);
const onReady = (sdk) => {
playground.value = sdk;
};
</script>
<template>
<LiveCodes template="vue" @sdk-ready="onReady" />
</template>
The SDK is only available after the playground initializes. Use sdkReady (React), @sdk-ready (Vue), or on:sdkReady (Svelte) to get a reference.
Source: docs/docs/sdk/react.mdx, docs/docs/sdk/vue.mdx — sdkReady section
// React - config changes use setConfig (no reload)
const [config, setConfig] = useState(initialConfig);
setConfig(newConfig); // Efficient update, no iframe reload
// React - other prop changes cause full reload
const [template, setTemplate] = useState('react');
setTemplate('vue'); // Destroys and recreates iframe
Changing config prop uses SDK's setConfig() method under the hood — efficient. Changing other props (template, params, loading) destroys and recreates the iframe.
If you need reactive changes, prefer updating config over changing other props.
Source: docs/docs/sdk/react.mdx — Reactive Props section
# React
npm install livecodes
import LiveCodes from 'livecodes/react';
# Vue 3
npm install livecodes
import LiveCodes from 'livecodes/vue';
# Svelte
npm install livecodes
import LiveCodes from 'livecodes/svelte';
# Solid
npm install livecodes
import LiveCodes from 'livecodes/solid';
# Preact
npm install livecodes
import LiveCodes from 'livecodes/preact';
# Web Components (CDN)
<script src="https://cdn.jsdelivr.net/npm/livecodes/web-components.js"></script>
All frameworks export:
Props — EmbedOptions plus framework-specific propsPlayground — SDK Playground interfaceConfig — Configuration typeCode — Code object typeLanguage — Language string typeMAmattpocock/skills288k近 7 天新增 10,178 个 star
AFaffaan-m/ECC278k近 7 天新增 4,046 个 star
FIfirecrawl/firecrawl191k近 7 天新增 2,010 个 star
用 React、Tailwind 和 shadcn/ui 构建多组件页面。
ANanthropics/skills181k近 7 天新增 1,119 个 star