Skip to main content
The change event (also called code event) is fired when the playground “content” changes.

Event Payload

The event callback receives an object with the following structure:
code
Code
required
An object containing the language, content and compiled code for each editor.
config
Config
required

When It Fires

The change event is triggered when any of the following changes:

Usage Example

import { createPlayground } from "livecodes";

createPlayground("#container").then((playground) => {
  // Listen for code changes
  const changeWatcher = playground.watch("code", ({ code, config }) => {
    console.log("Code changed!");
    console.log("Markup:", code.markup.content);
    console.log("Style:", code.style.content);
    console.log("Script:", code.script.content);
    console.log("Result HTML:", code.result);
    console.log("Project title:", config.title);
  });

  // Later, remove the watcher
  // changeWatcher.remove();
});

Common Use Cases

Auto-Save on Changes

let saveTimeout;

playground.watch("code", async ({ code, config }) => {
  // Debounce saving
  clearTimeout(saveTimeout);
  saveTimeout = setTimeout(async () => {
    console.log("Auto-saving...");
    const data = { code, config };
    await fetch("/api/save", {
      method: "POST",
      body: JSON.stringify(data),
    });
    console.log("Saved!");
  }, 2000);
});

Track Code Statistics

playground.watch("code", ({ code }) => {
  const totalLines = 
    code.markup.content.split("\n").length +
    code.style.content.split("\n").length +
    code.script.content.split("\n").length;
  
  const totalChars = 
    code.markup.content.length +
    code.style.content.length +
    code.script.content.length;
  
  console.log(`Total lines: ${totalLines}`);
  console.log(`Total characters: ${totalChars}`);
});

Mirror Code to Another Element

const previewElement = document.querySelector("#code-preview");

playground.watch("code", ({ code }) => {
  // Display the current script code elsewhere
  if (previewElement) {
    previewElement.textContent = code.script.content;
  }
});

Check Compiled Output

playground.watch("code", ({ code }) => {
  // See how TypeScript compiled to JavaScript
  if (code.script.language === "typescript") {
    console.log("TypeScript source:", code.script.content);
    console.log("Compiled JavaScript:", code.script.compiled);
  }
});

Sync with External Editor

let isExternalUpdate = false;

playground.watch("code", ({ code }) => {
  if (isExternalUpdate) {
    isExternalUpdate = false;
    return;
  }
  
  // Send changes to external system
  externalEditor.updateContent(code.script.content);
});

// When external editor changes
externalEditor.onChange((newContent) => {
  isExternalUpdate = true;
  playground.setConfig({
    script: { content: newContent }
  });
});

Using onChange() (Deprecated)

The onChange() method is deprecated. Use watch("code", ...) instead:
// ❌ Deprecated
playground.onChange(({ code, config }) => {
  console.log("Changed");
});

// ✅ Recommended
playground.watch("code", ({ code, config }) => {
  console.log("Changed");
});

Removing the Watcher

const watcher = playground.watch("code", ({ code, config }) => {
  console.log("Code changed");
});

// Stop watching for changes
watcher.remove();

Build docs developers (and LLMs) love