UNPKG

livecodes

Version:

A Code Playground That Just Works!

242 lines (180 loc) 5.96 kB
--- name: livecodes/sdk-embedding description: > Create and configure embedded playgrounds using createPlayground(), EmbedOptions, container setup, loading modes (eager/lazy/click), and appUrl for self-hosted instances. Load this skill when embedding LiveCodes in web pages, configuring playground containers, or setting up SDK integration. type: core library: livecodes library_version: 0.13.0 sources: - live-codes/livecodes:docs/docs/sdk/js-ts.mdx - live-codes/livecodes:src/sdk/index.ts - live-codes/livecodes:src/sdk/models.ts --- # LiveCodes — Create Embedded Playground LiveCodes is a client-side code playground that runs in the browser. Use `createPlayground` to embed interactive code editors in any web page. ## Setup ```javascript import { createPlayground } from 'livecodes'; // Minimal embed with template createPlayground('#container', { template: 'react', }); // Embed with custom code createPlayground('#container', { config: { markup: { language: 'html', content: '<h1>Hello World</h1>' }, style: { language: 'css', content: 'h1 { color: blue; }' }, script: { language: 'javascript', content: 'console.log("Hello");' }, }, }); // CDN usage (no bundler) import { createPlayground } from 'https://cdn.jsdelivr.net/npm/livecodes'; createPlayground('#container', { template: 'vue' }); ``` ## Core Patterns ### Load playground lazily Playgrounds load when they approach the viewport by default. Use `loading: 'eager'` for immediate load or `loading: 'click'` for click-to-load. ```javascript createPlayground('#container', { template: 'react', loading: 'click', // Shows "Click to load" screen }); ``` ### Configure via query params For simple cases, use URL-style params instead of full config objects. ```javascript createPlayground('#container', { params: { html: '<h1>Hello</h1>', css: 'h1 { color: blue; }', js: 'console.log("Hello")', console: 'open', }, }); ``` ### Use self-hosted instance Point to your own LiveCodes deployment. ```javascript createPlayground('#container', { appUrl: 'https://playground.mywebsite.com', template: 'react', }); ``` ### Multiple sources priority When providing multiple config sources, they override in order: `template` < `import` < `config` < `params`. ```javascript createPlayground('#container', { template: 'react', // Lowest priority import: 'https://gist.github.com/...', // Overrides template config: { /* ... */ }, // Overrides import params: { js: '...' }, // Highest priority }); ``` ### Generate shareable URL Create a link to the standalone app without embedding. ```javascript import { getPlaygroundUrl } from 'livecodes'; const url = getPlaygroundUrl({ config: { markup: { language: 'markdown', content: '# Hello World' }, }, }); // url = "https://livecodes.io/#config/..." ``` ### Compress config for sharing Compress a stringified config object for use in URL hashes or compact storage. ```javascript import { compress } from 'livecodes'; const config = { markup: { language: 'html', content: '<h1>Hello World</h1>' }, }; const compressed = compress(JSON.stringify(config)); ``` ### Decompress config Decompress a string that was compressed with `compress`. Returns `null` if decompression fails. ```javascript import { decompress } from 'livecodes'; const decompressed = decompress(compressedString); if (decompressed) { const config = JSON.parse(decompressed); } ``` ## Common Mistakes ### HIGH Container element not found throws error Wrong: ```javascript createPlayground('#nonexistent-container', { template: 'react' }); // Throws: "Cannot find element: \"#nonexistent-container\"" ``` Correct: ```javascript // Ensure container exists before calling const container = document.querySelector('#container'); if (container) { createPlayground('#container', { template: 'react' }); } // Or use headless mode (container optional) createPlayground({ view: 'headless', config: { /* ... */ }, }); ``` `createPlayground` throws if the container selector matches no elements. In headless mode (`headless: true`), the container parameter is optional. Source: src/sdk/index.ts — throws `"Cannot find element"` for invalid container ### HIGH Calling SDK methods after destroy() throws error Wrong: ```javascript const playground = await createPlayground('#container', options); await playground.destroy(); await playground.run(); // Throws: "Cannot call API methods after calling `destroy()`." ``` Correct: ```javascript const playground = await createPlayground('#container', options); await playground.run(); // Use SDK methods while playground exists... await playground.destroy(); // Last call — no more methods after this ``` Once `destroy()` is called, all subsequent SDK method calls throw with the message "Cannot call API methods after calling `destroy()`." Source: src/sdk/index.ts — `alreadyDestroyedMessage` constant ### MEDIUM Invalid appUrl throws error Wrong: ```javascript createPlayground('#container', { appUrl: 'my-playground', // Not a valid URL }); // Throws: "my-playground is not a valid URL." ``` Correct: ```javascript createPlayground('#container', { appUrl: 'https://playground.example.com', template: 'react', }); ``` The `appUrl` must be a parseable URL string. Use the full URL including protocol. Source: src/sdk/index.ts — URL parsing in `getPlaygroundUrl` ### MEDIUM SDK method timeout after 60 seconds SDK calls timeout after 60 seconds if the playground doesn't respond. ```javascript // This can timeout if playground has infinite loop or slow WASM load await playground.run(); // Times out after 60s ``` Handle with try/catch for long-running operations: ```javascript try { await playground.run(); } catch (error) { if (error.message.includes('timed out')) { console.error('Playground timed out'); } } ``` Source: src/sdk/index.ts — `API_TIMEOUT = 60_000` (60 seconds)