# Headless Mode
import LiveCodes from '../../src/components/LiveCodes.tsx';
The LiveCodes [SDK](../sdk/index.html.md) can be used to create playgrounds in headless mode. In this mode, no visible output is displayed in the embedding web page. However, all [SDK methods](../sdk/js-ts.html.md)#sdk-methods) are accessible (e.g. for [updating code](./js-ts.html.md)#setconfig), [getting compiled code](./js-ts.html.md)#getcode), console output, [result HTML](./js-ts.html.md)#getcode), [shareable URLs](./js-ts.html.md)#getshareurl), [formatting code](./js-ts.html.md)#format), [running tests](./js-ts.html.md)#runtests), etc).
This provides the power of leveraging the wide range of features and language support offered by LiveCodes, while retaining full control over the UI.
## Usage
To create a headless playground, set the [embed option](./js-ts.html.md)#embed-options) [`headless`](../sdk/js-ts.html.md)#headless) to `true`.
Please note that in headless mode, the first parameter (`container`) of the function [`createPlayground`](../sdk/js-ts.html.md)#createplayground) is optional and can be omitted.
"
console.log(code.result); // (result page HTML)
});
```
## Examples
The following examples show how to use the headless mode to make a Markdown editor, an MDX editor and a Python interpreter.
:::tip
You may want to view the following playgrounds in full screen (using the full screen button in the top right of each playground).
:::
### Markdown Editor
In this demo, code changes are watched using the SDK method [`watch('code', callback)`](./js-ts.html.md)#watch). The callback function accepts an argument which is an object with the properties `code` and `config` (see [`getCode`](./js-ts.html.md)#getcode) and [`getConfig`](./js-ts.html.md)#getconfig)). The compiled code is obtained as `code.markup.compiled`.
export const mdDemo = { markup: { language: 'html', content: `\n
Loading...
\n\n\x3Cscript type="module">\n import { createPlayground } from "https://cdn.jsdelivr.net/npm/livecodes@0.2.0";\n import debounce from "https://jspm.dev/debounce";\n\n const initialCode = "# Hello, LiveCodes!\\n\\n";\n\n // the code editor\n const editor = CodeMirror.fromTextArea(document.getElementById("editor"), {\n lineNumbers: true,\n mode: "markdown",\n });\n editor.setSize("100%", 200);\n editor.setValue(initialCode);\n\n // the playground\n const options = {\n view: "headless",\n };\n\n const livecodes = await createPlayground(options);\n await livecodes.load();\n\n const compile = async () => {\n await livecodes.setConfig({\n autoupdate: false,\n markup: {\n language: "markdown",\n content: editor.doc.getValue(),\n },\n });\n };\n\n // watch for changes\n editor.on("change", debounce(compile, 1000));\n livecodes.watch("code", ({ code, config }) => {\n createSandbox(document.querySelector("#output"), code.markup.compiled);\n });\n\n await compile();\n\n // create a sandbox for safe execution of compiled code\n function createSandbox (container, html) {\n const iframe = document.createElement("iframe");\n iframe.src = "https://livecodes-sandbox.pages.dev/v7/";\n iframe.sandbox =\n "allow-same-origin allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-presentation allow-scripts";\n iframe.onload = () => {\n iframe.contentWindow.postMessage({ html }, "*");\n };\n container.innerHTML = "";\n container.appendChild(iframe);\n return iframe;\n };\n\x3C/script>\n\n\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/lib/codemirror.js">\x3C/script>\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/mode/markdown/markdown.js">\x3C/script>\n\n\n` }}
### MDX Editor
In this demo, code changes are watched using the SDK method [`watch('code', callback)`](./js-ts.html.md)#watch). The callback function accepts an argument which is an object with the properties `code` and `config` (see [`getCode`](./js-ts.html.md)#getcode) and [`getConfig`](./js-ts.html.md)#getconfig)). The result HTML is obtained as `code.result`.
:::tip
If you do not want to run the result page in the headless playground and only want to get the generated result HTML, you can set the configuration option [`autoupdate](../configuration/configuration-object.html.md)#autoupdate) to `false`.
:::
export const mdxDemo = { markup: { language: 'html', content: `\n