🪐 🌐 Jupyter Embed
Jupyter Embed allows you to embed interactive Jupyter components (cells, notebooks, terminals, consoles) into any web page with just a script tag and HTML data attributes. Powered by the full Jupyter ecosystem.
Overview
Convert any website or blog into an interactive learning platform with Jupyter. No React knowledge required - just add HTML elements with data attributes.
Minimum HTML Example
Here's a complete, minimal HTML file that embeds an interactive Jupyter cell. Copy this and open it in your browser:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Jupyter Embed - Minimal Example</title>
<!-- Required for ipywidgets support -->
<script
data-jupyter-widgets-cdn="https://cdn.jsdelivr.net/npm/"
data-jupyter-widgets-cdn-only="true"
></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
</head>
<body>
<h1>My Interactive Code</h1>
<!-- Jupyter Cell -->
<div
data-jupyter-embed="cell"
data-jupyter-height="200px"
data-jupyter-auto-execute="true"
>
<code data-jupyter-source-code> print("Hello from Jupyter!") </code>
</div>
<!-- Load Jupyter Embed with configuration -->
<script
type="module"
src="https://jupyter-embed.datalayer.tech/jupyter-embed.lazy.js"
data-jupyter-server-url="https://oss.datalayer.run/api/jupyter-server"
data-jupyter-token="60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6"
data-jupyter-lazy-load="true"
data-jupyter-auto-start-kernel="true"
></script>
</body>
</html>
The example above uses Datalayer's public demo server. For production use, configure your own Jupyter Server.
Quick Start
1. Configure the Connection
<script
type="module"
src="https://jupyter-embed.datalayer.tech/jupyter-embed.lazy.js"
data-jupyter-server-url="https://oss.datalayer.run/api/jupyter-server"
data-jupyter-token="60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6"
data-jupyter-lazy-load="true"
data-jupyter-auto-start-kernel="true"
></script>
2. Add Required Scripts
<!-- Required for ipywidgets support -->
<script
data-jupyter-widgets-cdn="https://cdn.jsdelivr.net/npm/"
data-jupyter-widgets-cdn-only="true"
></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
3. Add Embed Elements
<div data-jupyter-embed data-type="cell" data-height="200px">
<code data-type="source-code"> print("Hello, Jupyter!") </code>
</div>
That's it! The script automatically finds and initializes all elements with data-jupyter-embed.
Installation
- CDN
- ES Module
- npm
<!-- IIFE bundle (adds JupyterEmbed global) -->
<script src="https://jupyter-embed.datalayer.tech/jupyter-embed.js"></script>
<script type="module">
import {
configureJupyterEmbed,
initJupyterEmbeds,
} from 'https://jupyter-embed.datalayer.tech/jupyter-embed.esm.js';
</script>
import {
configureJupyterEmbed,
initJupyterEmbeds,
} from '@datalayer/jupyter-embed';
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
serverUrl | string | '' | Jupyter server URL |
wsUrl | string | auto | WebSocket URL (derived from serverUrl) |
token | string | '' | Authentication token |
defaultKernel | string | 'python3' | Default kernel name |
autoStartKernel | boolean | true | Auto-start kernel on load |
lazyLoad | boolean | true | Only initialize when visible |
theme | 'light' | 'dark' | 'light' | UI theme |
Component Types
Code Cell
Interactive code cell with execution capability:
<div
data-jupyter-embed
data-type="cell"
data-cell-type="code"
data-height="200px"
data-auto-execute="false"
>
<code data-type="source-code">
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 10,
100) plt.plot(x, np.sin(x)) plt.show()
</code>
</div>
Attributes:
data-cell-type:code|markdown|rawdata-height: CSS height valuedata-auto-execute: Run on load (true/false)data-show-toolbar: Show cell toolbardata-kernel: Kernel name override
Markdown Cell
<div data-jupyter-embed data-type="cell" data-cell-type="markdown">
<code data-type="source-code">
# Welcome to Jupyter! This is **markdown** with: - Lists - *Formatting* -
And more!
</code>
</div>
Notebook
Full notebook from a file path or inline content:
- From Path
- Inline Content
<div
data-jupyter-embed
data-type="notebook"
data-path="notebooks/demo.ipynb"
data-height="500px"
data-show-toolbar="true"
></div>
<div data-jupyter-embed data-type="notebook" data-height="400px">
<script type="application/json">
{
"cells": [
{
"cell_type": "markdown",
"source": ["# My Inline Notebook"]
},
{
"cell_type": "code",
"source": ["print('Hello!')"]
}
],
"metadata": {
"kernelspec": { "name": "python3" }
},
"nbformat": 4,
"nbformat_minor": 4
}
</script>
</div>
Terminal
Full terminal session:
<div
data-jupyter-embed
data-type="terminal"
data-height="300px"
data-color-mode="dark"
></div>
Console
Jupyter console (REPL):
<div
data-jupyter-embed
data-type="console"
data-height="400px"
data-kernel="python3"
>
<code data-type="pre-execute-code">
# This runs when the console starts import numpy as np import pandas as pd
</code>
</div>
Output Display
Display pre-computed outputs without a kernel:
<div data-jupyter-embed data-type="output">
<script type="application/json">
[
{
"output_type": "stream",
"name": "stdout",
"text": "Hello, World!\n"
},
{
"output_type": "execute_result",
"data": {
"text/html": "<h3>Rich HTML Output</h3>"
}
}
]
</script>
</div>
JavaScript API
For advanced control, use the JavaScript API:
// Configure connection
JupyterEmbed.configureJupyterEmbed({
serverUrl: 'http://localhost:8888',
token: 'your-token',
defaultKernel: 'python3',
lazyLoad: true,
});
// Initialize all embeds on page
JupyterEmbed.initJupyterEmbeds();
// Initialize embeds added dynamically (e.g., after AJAX)
JupyterEmbed.initAddedJupyterEmbeds(containerElement);
// Render programmatically
const element = document.getElementById('my-embed');
JupyterEmbed.renderEmbed(element, {
type: 'cell',
source: 'print("Hello")',
autoExecute: true,
});
// Clean up
JupyterEmbed.destroyJupyterEmbeds();
Styling
Hide uninitialized embeds to prevent flash of unstyled content:
[data-jupyter-embed]:not([data-jupyter-initialized]) {
visibility: hidden;
min-height: 100px;
}
Server Requirements
Your Jupyter server needs to:
- Accept CORS connections from your domain
- Have authentication configured (token or none)
- Support WebSocket connections
Example server configuration:
jupyter server \
--ServerApp.allow_origin='*' \
--ServerApp.token='your-token' \
--ServerApp.disable_check_xsrf=True
Use Cases
Interactive Tutorials
<h2>Learn Python</h2>
<p>Try running this code:</p>
<div data-jupyter-embed data-type="cell">
<code data-type="source-code">
# Your first Python program name = "World" print(f"Hello, {name}!")
</code>
</div>
<p>Now try changing the name!</p>
Documentation with Live Examples
<h2>API Reference: numpy.linspace</h2>
<p>Creates evenly spaced numbers over an interval.</p>
<div data-jupyter-embed data-type="cell" data-auto-execute="true">
<code data-type="source-code">
import numpy as np np.linspace(0, 10, 5) # 5 numbers from 0 to 10
</code>
</div>
Blog Posts
<article>
<h1>Data Visualization with Matplotlib</h1>
<p>Let's create a simple plot:</p>
<div data-jupyter-embed data-type="cell" data-height="400px">
<code data-type="source-code">
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0,
2*np.pi, 100) plt.figure(figsize=(10, 6)) plt.plot(x, np.sin(x),
label='sin(x)') plt.plot(x, np.cos(x), label='cos(x)') plt.legend()
plt.title('Trigonometric Functions') plt.show()
</code>
</div>
</article>
Related
- @datalayer/jupyter-react - Core React components
- @datalayer/jupyter-lexical - Rich document editor