Skip to content

Code Block

The Code block lets you embed custom HTML, CSS, and JavaScript into your lessons. Use it to build interactive elements, custom visualizations, or any content that goes beyond the standard block types.

The block gives you a single editor for a complete HTML document. Type or paste the full document, including any <style> and <script> tags, and Slate renders it inside a sandboxed container in the course player.

There are two ways to fill the editor:

  1. Generate with AI. Describe what you want in plain language and Slate writes the snippet for you.
  2. Paste or write your own HTML. Use a snippet from a designer, an external AI tool, or your own code. Slate treats the content as a single document.

The code editor includes:

  • Syntax highlighting for HTML, CSS, and JavaScript in both light and dark themes
  • Undo and redo with keyboard shortcuts (⌘Z / ⇧⌘Z on Mac, Ctrl+Z / Ctrl+Shift+Z on Windows and Linux)
  • Auto-formatting (js-beautify)
  • Copy to clipboard
  • Download as .html file
  • Character count

Click Generate to describe what you want to build in plain language. Slate generates a complete, self-contained HTML snippet that fits the course theme. Code generation costs 100 AI credits.

Your code has access to CSS variables from the course theme:

  • --primary-color, --hover-color - brand colors
  • --border-radius - corner rounding
  • --text-color, --text-muted - text colors
  • --bg-light, --bg-muted - background colors
  • --border-color - border color
  • --success-color, --error-color - status colors

These variables adapt automatically to the course theme.

Code blocks run in an isolated container. If you are writing code yourself or pasting output from an external AI tool, these rules apply.

Your JavaScript has access to container, which points to the block’s root DOM element. It does not have access to document, window, fetch, localStorage, or other browser APIs outside the block. Use container.querySelector() instead of document.querySelector() to target elements inside your block.

The player sanitizes code block HTML before it renders, and strips any id value that collides with a property name on window or document. The stripped ids include title, name, body, head, location, cookie, domain, length, and constructor, among others. The id is removed silently, so container.querySelector('#title') returns nothing and the interaction looks broken with no visible error.

Use classes or data-* attributes as script hooks instead:

<h2 class="detail-title" data-role="title">Elimination</h2>
const el = container.querySelector('.detail-title');
// or: const el = container.querySelector('[data-role="title"]');

These are shadowed as undefined inside the sandbox:

  • document, window, parent, top, self, frames, globalThis
  • localStorage, sessionStorage
  • fetch, XMLHttpRequest, WebSocket, postMessage
  • eval and the Function constructor
  • The static methods on Object, Array, Proxy, and Reflect. Array and object literals ([1, 2, 3], { a: 1 }) and instance methods (arr.map(), arr.forEach()) still work, but calls like Object.keys(obj), Object.assign(a, b), Array.from(nodeList), and Array.isArray(x) will throw.

Safe replacements for the blocked static methods:

  • Array.from(nodeList) becomes [...nodeList] or nodeList.forEach(...)
  • Object.keys(obj) becomes a for (const key in obj) loop
  • Object.assign(a, b) becomes { ...a, ...b }

The in-app Help dialog on the code block includes a ready-made AI prompt template that bakes these rules in. Copy it before asking ChatGPT or Claude to build a snippet.