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>
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: