RunKit Embed

Embed node.js on any website


It’s easy to embed RunKit on any website. The embedded version of a RunKit notebook has a single executable code cell. It will grow and shrink vertically to fit its content, and fill its container horizontally. You can have as many instances as you like on a given page.

Table of Contents

Common use cases

There are two ways to get RunKit on your page, described below. In both cases, you want to include:
<script src="https://embed.runkit.com"></script>


1. Attaching RunKit to an existing element

This is the easiest way to embed RunKit. Just include one script tag, and let it know which element contains the source code you want to attach to with the data-element-id attribute.

<h3 style="text-align: center;">Welcome to my website</h3> <script src="https://embed.runkit.com" data-element-id="my-element"></script> <!-- anywhere else on your page --> <div id="my-element">// GeoJSON! var getJSON = require("async-get-json"); await getJSON("https://storage.googleapis.com/maps-devrel/google.json");</div>

2. Programmatically creating an Embed

You can also create an embedded notebook programmatically. Just include the same script tag, then call RunKit.createNotebook.

<h3 style="text-align: center;">Welcome to my website</h3> <script src="https://embed.runkit.com"></script> <div id="my-element"></div> <script>var notebook = RunKit.createNotebook({ // the parent element for the new notebook element: document.getElementById("my-element"), // specify the source of the notebook source: "// GeoJSON!\nvar getJSON = require(\"async-get-json\");\n\nawait getJSON(\"https://storage.googleapis.com/maps-devrel/google.json\");" })</script>

Embed API

The RunKit <script> tag adds aRunKit object to the global namespace, which looks like this (as a TypeScript type definition):

interface GlobalRunKit { createNotebook: (options: EmbedOptions) => NotebookEmbed }

RunKit.createNotebook creates an embedded notebook using the provided options, and returns aNotebookEmbed object. The options are (again, as a TypeScript type definition):

// A semver range as a string. For example: "10.1.x" or "12.x.x". // See https://docs.npmjs.com/about-semantic-versioning type semverRange = string // A string that represents CSS Pixels. A string that has a number with the 'px' // suffix. For example: "10px". // See https://developer.mozilla.org/en-US/docs/Glossary/CSS_pixel type cssPxString = string interface EmbedOptions { element: HTMLElement // Parent element for the new notebook // Environment variables for the execution environment. Available under // `process.env`. Defaults to [] environment?: Array<{name: string, value: string}> evaluateOnLoad?: boolean // Evaluate the Embed when it finishes loading. // Where the line numbers should appear. Defaults to "outside" gutterStyle?: "inside" | "none" | "outside" // Hides the "▶ Run" button. In Endpoint mode, Hides the endpoint URL. hidesActionButton?: boolean // In Endpoint mode, Hides the logs that would appear when hitting the Endpoint. // See https://runkit.com/docs/endpoint. hidesEndpointLogs?: boolean // Minimum height of the embed in pixels. E.g. "100px". Defaults to "73px" minHeight?: cssPxString // When in default mode RunKit Embeds behave like a regular notebook and display // outputs after each evaluation. When the Embed is in endpoint mode the outputs // are replaced by endpoint logs and a URL is provided to run the Embed code. See // https://runkit.com/docs/endpoint. Defaults to "default" mode?: "endpoint" | "default" // A semver range that the node engine should satisfy, e.g. "4.0.x" or "> // 6.9.2". Defaults to "10.x.x" nodeVersion?: semverRange source?: string // The source code of the Embed. // The timestamp in UTC milliseconds to recreate the state of package // availability. No packages published to npm after this time are available in this // embed. Useful for reproducing bugs, or guaranteeing dependency versions. By // default the timestamp is set to the time the embed is created. packageTimestamp?: number | null // Code in the preamble field will not be displayed in the embed, but will be // executed before running the code in the embed. For example, libraries that use // RunKit for documentation often require their package in the preamble to avoid // clutter in the embed code. preamble?: string readOnly?: boolean tabSize?: number // An Integer Minimum of 0 Defaults to 4 title?: string // The title of the RunKit Notebook when it is saved on RunKit. }

The key?: value syntax above means that the key is optional.

The NotebookEmbed object returned byRunKit.createNotebook has the following interface: (Note that the getters and setters are all async and return Promises. This is because they travel across an iframe.)

interface NotebookEmbed { /// Methods destroy: () => void evaluate: () => void /// Events onEvaluate: () => void // Called when a cell is evaluated. // Called when the Embed has fully loaded. The function will be passed a // reference to the Embed. onLoad: (arg: NotebookEmbed) => void // Called when the embed cell is resized. onResize: (arg: {height: number}) => void onSave: () => void // Called when the embed is saved. // Called when the shareable URL or endpoint URL changes. onURLChanged: (arg: {shareableURL: string, endpointURL: string}) => void /// Properties // endpointURL // In Endpoint mode, this is the url that will run this code // when visited. See https://runkit.com/docs/endpoint. getEndpointURL: () => Promise<string> // environment // Environment variables for the execution environment. // Available under `process.env`. Defaults to [] getEnvironment: () => Promise<Array<{name: string, value: string}>> setEnvironment: (environment: Array<{name: string, value: string}>) => Promise<undefined> // evaluateOnLoad // Evaluate the Embed when it finishes loading. getEvaluateOnLoad: () => Promise<boolean> // gutterStyle // Where the line numbers should appear. Defaults to "outside" getGutterStyle: () => Promise<"inside" | "none" | "outside"> setGutterStyle: (gutterStyle: "inside" | "none" | "outside") => Promise<undefined> // hidesActionButton // Hides the "▶ Run" button. In Endpoint mode, Hides the endpoint URL. getHidesActionButton: () => Promise<boolean> setHidesActionButton: (hidesActionButton: boolean) => Promise<undefined> // hidesEndpointLogs // In Endpoint mode, Hides the logs that would appear when // hitting the Endpoint. See https://runkit.com/docs/endpoint. getHidesEndpointLogs: () => Promise<boolean> setHidesEndpointLogs: (hidesEndpointLogs: boolean) => Promise<undefined> // minHeight // Minimum height of the embed in pixels. E.g. "100px". Defaults to "73px" getMinHeight: () => Promise<cssPxString> setMinHeight: (minHeight: cssPxString) => Promise<undefined> // mode // When in default mode RunKit Embeds behave like a regular notebook // and display outputs after each evaluation. When the Embed is in endpoint mode // the outputs are replaced by endpoint logs and a URL is provided to run the Embed // code. See https://runkit.com/docs/endpoint. Defaults to "default" getMode: () => Promise<"endpoint" | "default"> setMode: (mode: "endpoint" | "default") => Promise<undefined> // nodeVersion // A semver range that the node engine should satisfy, e.g. // "4.0.x" or "> 6.9.2". Defaults to "10.x.x" getNodeVersion: () => Promise<semverRange> setNodeVersion: (nodeVersion: semverRange) => Promise<undefined> // source getSource: () => Promise<string> // The source code of the Embed. setSource: (source: string) => Promise<undefined> // packageTimestamp // The timestamp in UTC milliseconds to recreate the state // of package availability. No packages published to npm after this time are // available in this embed. Useful for reproducing bugs, or guaranteeing dependency // versions. By default the timestamp is set to the time the embed is created. getPackageTimestamp: () => Promise<number | null> setPackageTimestamp: (packageTimestamp: number | null) => Promise<undefined> // preamble // Code in the preamble field will not be displayed in the embed, // but will be executed before running the code in the embed. For example, // libraries that use RunKit for documentation often require their package in the // preamble to avoid clutter in the embed code. getPreamble: () => Promise<string> setPreamble: (preamble: string) => Promise<undefined> // readOnly getReadOnly: () => Promise<boolean> setReadOnly: (readOnly: boolean) => Promise<undefined> // shareableURL // A URL that can be used to share the Embed with other users. getShareableURL: () => Promise<string> // requirePath // A path that can be used to require this Embed as a module in // other Embeds or RunKit Notebook. getRequirePath: () => Promise<string> // tabSize getTabSize: () => Promise<number> // An Integer Minimum of 0 Defaults to 4 setTabSize: (tabSize: number) => Promise<undefined> // title // The title of the RunKit Notebook when it is saved on RunKit. getTitle: () => Promise<string> setTitle: (title: string) => Promise<undefined> }

You can integrate these types into your editor by downloading our RunKit.d.ts type declaration file. VS Code will automatically detect the declaration file if it's in your project, so you'll have IntelliSense working even if you are using Vanilla JavaScript.


Examples

We've covered some simple examples in Common use cases. Here we'll walk through a couple more intricate examples.

1. Change the style of the gutter

This examples demonstrates styling the gutter. Valid options for gutter are "inside", "outside", or "none".

<script src="https://embed.runkit.com"></script> <style>.embed { overflow: visible; }</style> <pre class="embed" data-gutter="inside">console.log("hello inside"); 1 + 1</pre> <pre class="embed" data-gutter="outside">console.log("hello outside"); 1 + 1</pre> <pre class="embed" data-gutter="none">console.log("hello none"); 1 + 1</pre> <script> const elements = [...document.getElementsByClassName('embed')] const notebooks = elements.reduce((notebooks, element) => { const innerText = element.firstChild const currentCell = window.RunKit.createNotebook({ element, gutterStyle: element.getAttribute("data-gutter"), source: innerText.textContent, // Remove the text content of the pre tag after the embed has loaded onLoad: () => innerText.remove() }) return notebooks }, []) </script>

2. Web Components

Use RunKit as a custom element. This example defines rk-embed as a new custom element.

<script src="https://embed.runkit.com"></script> <rk-embed>console.log("hello world")</rk-embed> <script> class RunKitEmbed extends HTMLElement { constructor() { super(); const wrapper = document.createElement('div') wrapper.style = "margin: 20pt" const source = this.textContent this.textContent = "" const tempCodePlaceholder = document.createElement('pre') tempCodePlaceholder.textContent = source window.RunKit.createNotebook({ element: wrapper, source, onLoad: () => tempCodePlaceholder.remove() }) this.appendChild(wrapper) this.appendChild(tempCodePlaceholder) } } customElements.define('rk-embed', RunKitEmbed); </script>

Bindings


OEmbed

Embed existing notebooks with OEmbed

Our OEmbed endpoint is available at: https://embed.runkit.com/oembed. Example OEmbed link

We support only the JSON format for responses. See the OEmbed documentation for information about how to implement the protocol. RunKit does support auto-discovery of notebooks.

Dynamic Height

RunKit Embeds are highly interactive, and as a result they want to change height in response to user interaction. If you're using RunKit with Embed.ly, using their Platform.js library will make sure everything works smoothly. If you're using OEmbed directly, you'll want to include this script, or something similar, on your page to listen to changes in the Embed's height:

<script> window.addEventListener('message', function(e) { if (e.origin !== "https://runkit.com") return; try { var data = JSON.parse(e.data); } catch (e) { return false; } if (data.context !== 'iframe.resize') { return false; } var iframe = document.querySelector('iframe[src="' + data.src + '"]'); if (!iframe) { return false; } if (data.height) { iframe.height = data.height; } }); </script>

This code is not RunKit specific, and it's how many sites implement this behavior. It's a simple protocol for an iframe to message its parent requesting the height of the frame be changed.

Showcase

RunKit Embeds are used on many websites for documentation, to provide examples in a blog post, or to let visitors run a code snippet. Check out these sites using RunKit embeds to enhance their pages: