Re-add JupyterHub as a launch target, done properly this time. The previous implementation was removed in #87 / #152; this issue captures what it would take to bring the capability back in a form that would actually work.
Why the old one was removed
Not because JupyterHub is unwanted — because that implementation could only ever address one hub. Three defects, all verified against a live build:
| Defect |
Consequence |
| No config key at all — the hub URL was typed by the reader into a text box |
Rendered unconditionally on every site, including Colab-only ones |
The URL lived in React.useState('') |
Discarded when the popover closed; had to be retyped for every single launch |
A /jupyter/hub/ path segment was hardcoded in the URL builder |
Only addressed hubs at <host>/jupyter/hub/; a stock JupyterHub at /hub/user-redirect/ returned 404, and the reader could not compensate from the box |
The Sphinx book-theme does not have the third problem: it builds {jupyterhub_url}/user-redirect/git-pull?… and leaves the entire prefix to configuration, so any hub layout works. That is the key design constraint for this issue — the deployment shape belongs in config, never in the builder.
What to build
Configuration, not reader input. A site.options key (launch_jupyterhub_url, say) alongside the existing launch_repo_suffix / launch_branch / launch_repo_url / launch_notebooks_path / launch_source_path family. The control renders only when the key is set, mirroring how launch.py appends its hub button only when jupyterhub_url is present. That alone fixes defects 1 and 2, and putting the whole prefix in the configured value fixes 3.
URL shape (book-theme launch.py, for reference):
{jupyterhub_url}/user-redirect/git-pull?repo={repo_url}&urlpath={ui_pre}/{repo}/{subpath}{page}.ipynb&branch={branch}
Most of the inputs already exist as tested pure functions in app/components/toolbar/launchUrls.ts — notebookOrgRepo and notebookRelPath survived the removal and are shared with the Colab builder, so this is a new URL template over existing parts rather than new path logic.
notebook_interface parity. The book-theme maps classic → tree and jupyterlab → lab/tree in the urlpath. The removed MyST version hardcoded tree. Worth carrying across, as JupyterLab is the more likely default on a modern hub.
The open design question
The toolbar's Launch control is now a plain anchor to Colab (#152). Adding a second target means reintroducing a chooser of some kind — which is exactly what was just deleted, so it should not be reintroduced casually. Options worth weighing: a small dropdown on the existing control, a separate toolbar item that appears only when configured, or a per-project setting that selects one primary target rather than offering a menu.
This overlaps with #128 (live-compute toggle placement and integration), which is already reviewing what belongs in that toolbar. The two should be settled together rather than separately, to avoid a second round of churn.
Related but distinct
Connecting to a hub-spawned kernel for in-page execution is a different capability — that runs through Thebe, not an nbgitpuller link, and is covered by the local/remote server issue filed alongside this one. This issue is only about the launch link that sends a reader to a hub.
Priority
Demand-driven. No lecture repo has ever configured a hub in the Sphinx theme (jupyterhub_url appears in no _config.yml across the org), so there is no known user waiting on this. It should be built when someone asks, not speculatively — the same standard applied in #87.
Re-add JupyterHub as a launch target, done properly this time. The previous implementation was removed in #87 / #152; this issue captures what it would take to bring the capability back in a form that would actually work.
Why the old one was removed
Not because JupyterHub is unwanted — because that implementation could only ever address one hub. Three defects, all verified against a live build:
React.useState('')/jupyter/hub/path segment was hardcoded in the URL builder<host>/jupyter/hub/; a stock JupyterHub at/hub/user-redirect/returned 404, and the reader could not compensate from the boxThe Sphinx book-theme does not have the third problem: it builds
{jupyterhub_url}/user-redirect/git-pull?…and leaves the entire prefix to configuration, so any hub layout works. That is the key design constraint for this issue — the deployment shape belongs in config, never in the builder.What to build
Configuration, not reader input. A
site.optionskey (launch_jupyterhub_url, say) alongside the existinglaunch_repo_suffix/launch_branch/launch_repo_url/launch_notebooks_path/launch_source_pathfamily. The control renders only when the key is set, mirroring howlaunch.pyappends its hub button only whenjupyterhub_urlis present. That alone fixes defects 1 and 2, and putting the whole prefix in the configured value fixes 3.URL shape (book-theme
launch.py, for reference):Most of the inputs already exist as tested pure functions in
app/components/toolbar/launchUrls.ts—notebookOrgRepoandnotebookRelPathsurvived the removal and are shared with the Colab builder, so this is a new URL template over existing parts rather than new path logic.notebook_interfaceparity. The book-theme mapsclassic→treeandjupyterlab→lab/treein theurlpath. The removed MyST version hardcodedtree. Worth carrying across, as JupyterLab is the more likely default on a modern hub.The open design question
The toolbar's Launch control is now a plain anchor to Colab (#152). Adding a second target means reintroducing a chooser of some kind — which is exactly what was just deleted, so it should not be reintroduced casually. Options worth weighing: a small dropdown on the existing control, a separate toolbar item that appears only when configured, or a per-project setting that selects one primary target rather than offering a menu.
This overlaps with #128 (live-compute toggle placement and integration), which is already reviewing what belongs in that toolbar. The two should be settled together rather than separately, to avoid a second round of churn.
Related but distinct
Connecting to a hub-spawned kernel for in-page execution is a different capability — that runs through Thebe, not an nbgitpuller link, and is covered by the local/remote server issue filed alongside this one. This issue is only about the launch link that sends a reader to a hub.
Priority
Demand-driven. No lecture repo has ever configured a hub in the Sphinx theme (
jupyterhub_urlappears in no_config.ymlacross the org), so there is no known user waiting on this. It should be built when someone asks, not speculatively — the same standard applied in #87.