Playground — Tips & Tricks

Playground tricks: dose Live mode, understand the sandbox, keep SCSS and PHP mode under control, lose nothing, and sidestep the usual pitfalls.

Back to the overview: Playground · Open the tool: www.jpkc.com/tools/playground/

The manual explains every feature, the examples show the workflows. This page is about what both assume but rarely state: how to dose the Live mode, what the sandbox really means, and which pitfalls cost you time. The interface is in English, so the real button and label names appear in the original.

Use Live mode wisely

  • Turn Live off for "expensive" code. Live mode rebuilds the preview after every input (slightly delayed). With compute-heavy JS, lots of animation, or constant re-rendering, that gets choppy. Then turn the Live checkbox off and rebuild deliberately with Run (Ctrl/Cmd+Enter) — you keep control over when rendering happens.
  • Watch out for infinite loops. Your JS runs in the preview <iframe> of the same browser. A while(true) loop or an accidental runaway freezes the preview (in the extreme, the whole tab). Before testing suspect loop logic, turn Live off so a half-finished infinite loop doesn't start while you're still typing — then run it under control with Run.
  • HTML Source as a sanity check. When the preview isn't showing what you expect, switch the preview header to HTML Source. There you see the full document the Playground builds — including the order of assets, <style>, and your script at the body's end. Often a problem explains itself right there.

Understand the sandbox

The preview runs in a sandbox <iframe> without allow-same-origin. That has consequences that have nothing to do with your code and everything to do with the environment:

  • No shared storage with the host page. The preview code has no access to the Playground's cookies, LocalStorage, or DOM. That's intentional (security) — but it explains why some "normally working" browser APIs behave differently in the preview.
  • Third-party scripts stay out, fetch may fail on CORS. The preview inherits the tool page's Content Security Policy: the browser blocks scripts and stylesheets via <script src>/<link> from third-party servers (a CDN, say). Allowed are the libraries from the asset dropdown, Google Fonts, and images via https:; third-party <iframe> embeds and audio and video from third-party servers stay out as well. fetch() against https: APIs is permitted — but since the preview document has an opaque origin, the call fails if the API doesn't send open CORS headers. That's not a Playground bug — it's browser security.
  • prompt/alert/popups work. The sandbox deliberately allows allow-modals and allow-popups — the demo example uses prompt(), and that works.
  • The "new tab" is the exception. Open preview in new tab opens your document as a normal page without a sandbox — in the tool page's origin, no less. That's exactly when things run that only the embedded <iframe>'s sandbox blocks. The tool page's Content Security Policy still applies there, though, so CDN scripts stay out in the new tab as well. Handy for full-fledged testing, but code there could also reach the tool page's LocalStorage, your snippets included. So only run code in the new tab that you trust.

Persistence: lose nothing

  • Auto-save is browser- and device-bound. Your state lives in this browser's LocalStorage. A different machine, a different browser, private/incognito mode, or cleared browser data means the state isn't there — or is gone. Don't rely on auto-save alone for anything important.
  • For permanence: Export HTML. Whatever you want to keep, export as a standalone .html file — it then lives outside the browser and can be brought back with Import HTML (see Example 6).
  • Snippets are limited and local. A maximum of eight named snippets, also only in LocalStorage. An identical name overwrites without further prompt — so give unique names if you want to keep variants side by side.
  • Load and Del don't ask. Load replaces your current working state immediately, Del deletes a snippet immediately. If you want to keep what you have, save it as a snippet yourself before loading another one.
  • SCSS source belongs in a snippet, not in an export. Export HTML writes the compiled CSS into the file; your SCSS code and the SCSS mode aren't in it. A snippet, on the other hand, stores the source along with the mode, and the CSS panel's Download hands it to you as playground.scss.
  • Reset deletes no snippets. The reset button only clears the current working state and loads the demo example; saved snippets stay. Conversely: an accidental reset is no disaster, as long as you saved anything important as a snippet or file first.

Common pitfalls

  • The HTML panel is the body only. Don't write a <!DOCTYPE>, <html>, or <head> here — the Playground adds the scaffold. What you need (meta tags, your own inline <style> and <script> blocks) still works; it goes into the generated document. Scripts and stylesheets from third-party servers, on the other hand, are blocked by the Content Security Policy (see above).
  • Inline handlers need function declarations. The Playground wraps your JS in a try { … } block at the end of the <body>. A function myFn() {} declaration still becomes global and is reachable for onclick="myFn()" from the HTML. Define the same logic as const myFn = () => …, though, and it only exists inside that block — the inline handler won't find it. So use function declarations for inline handlers (or bind events in the JS via addEventListener).
  • No import in the JS panel. For the same reason, import, export, and top-level await are syntax errors in the JS panel. For module code, put your own <script type="module"> in the HTML panel — although the Content Security Policy blocks imports from third-party servers there too.
  • Not every error carries the prefix. [Playground JS] only precedes errors thrown during your script's first pass. Errors in click handlers or timers, and syntax errors, land in the console as ordinary messages — so don't search for the prefix alone.
  • Bootstrap components need Bootstrap JS. Bootstrap CSS alone gives you layout and looks, but modals, dropdowns, or tooltips stay dead. Also enable Bootstrap JS (includes Popper) in the Assets dropdown. Dark Mode, in turn, is only selectable when Bootstrap CSS is active.
  • Closing tags in your code are safe. If you write a string with </script> in your JS or a </style> in your CSS, the Playground escapes it when building the preview — so your code doesn't tear open the generated document. On export this escaping is kept in the interest of a runnable document and is reversed again on import.
  • The SCSS compiler loads only the first time. The very first SCSS run briefly shows "Loading SCSS compiler…" because Dart Sass is lazy-loaded. After that it's there. An SCSS syntax error doesn't break anything but lands as an error message (with a line number) and as a CSS comment in the preview.

SCSS with Dart Sass

  • Write modern Sass. The Playground compiles with Dart Sass. Instead of the old global functions, use the built-in modules: @use 'sass:math'; for math.div() instead of / as division, @use 'sass:color'; for color.adjust() or color.scale(). The @use lines go at the top of the panel, before any other rules.
  • You won't see warnings here. So that every half-typed version doesn't spit out deprecation warnings, Dart Sass runs silently in the Playground — @warn and @debug produce no output either. To find out whether your code uses deprecated syntax, paste it into the Compiler; it shows warnings and @debug output.
  • Everything in one panel. Your own partials via @use 'file' or @import aren't available — there's no filesystem. Variables, mixins, and functions you'd normally split out simply go at the top of the SCSS panel.
  • Colors look different in the output than you expect. Dart Sass sometimes writes computed colors as rgb() with percentage values instead of hex. That's valid CSS, not a bug.

Master the PHP mode

  • No live preview — and that's a good thing. In PHP mode, PHP runs via WebAssembly on the main thread. An infinite loop couldn't be aborted from the outside and would freeze the tab. That's why there's deliberately no auto-run as you type: you always rebuild under control with Run PHP (Ctrl/Cmd+Enter). With suspect loop logic, finish writing first, then run.
  • Code can run without Run PHP. Switching PHP mode on, reloading with PHP mode active, loading a PHP snippet, importing a PHP file, any change in the Assets dropdown, and the SCSS switch each run your code once. If there's a risky loop in the panel right now, leave those controls alone until it's defused.
  • Every run starts from scratch. Before each execution the Playground resets the interpreter and the virtual filesystem. Whatever a run writes via file_put_contents() or holds in variables is gone on the next run — which keeps results reproducible.
  • Errors are in the PHP Log, not the output. PHP is configured so that warnings, notices, and errors don't pollute the preview but land in the PHP Log (with a line number). If the preview stays empty or doesn't show what you expect, the log is the first place to look — the red badge on the button already tells you whether something's pending. Your own error_log(...) lands there too.
  • The first start takes a moment. On activation around 13 MB of PHP engine is loaded — once, and only online. After that it's in the browser cache. Turn PHP off again and the Playground releases the memory.
  • A PHP export isn't standalone. An Export HTML in PHP mode contains the raw HTML+PHP source (playground.php.html) — re-importable, but not runnable in the browser on its own, because the PHP is unexecuted. For a finished, running document, render it with Run PHP first: the HTML Source view then shows the complete rendered document for copying, and in PHP mode Open preview in new tab opens exactly that last rendered output. Or switch the mode back off for pure front-end.
  • No server, no database. The mode runs PHP logic, but without a web server, DB, or filesystem on your machine. Ideal for snippets, functions, and language features — not a replacement for a real PHP environment.

Combine with other JPKCom tools

The Playground is for trying things out — for everything around it there are more specialized tools:

  • Compiler — when a snippet turns into production code: compile SCSS to CSS for good with the same Dart Sass (with visible warnings there) and minify or beautify HTML/JS/CSS. Useful once you want to ship the Playground state.
  • Beautify — format (and de-obfuscate) someone else's minified or tangled code first, before you drop it into the Playground to understand it.
  • Source Viewer — when you only want to read and highlight code rather than run it — for 100+ languages.

More context: the overview for the big picture, the manual for every feature, and the examples for the step-by-step workflows. You can try all of it directly in the tool.