You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #147 (parity study 2026-09-11 — content correctness).
Revised in place 2026-09-11 after the maintainer review:
Decided: the Launch control becomes opt-in and explicitly configured, with option names designed for more launch services.
Deferred: whether and where the theme checks that a notebook exists before showing Launch. The options are documented below.
The revision is recorded in the comments.
Problem
The Launch control (in the desktop toolbar and the mobile overflow menu) appears on every page of any project that sets project.github. It opens Colab on a notebook repository whose name the theme guesses: the source repository, minus any .myst suffix, plus .notebooks. Only launch_repo_url or launch_repo_suffix override the guess, and no option hides the control. A site without a notebooks repository therefore links readers to Colab on a repository that does not exist. For example, lecture-wasm's /cobweb/ opens https://colab.research.google.com/github/QuantEcon/lecture-wasm.notebooks/blob/main/cobweb.ipynb, and that repository returns 404 (verified 2026-09-11).
The book theme never guesses. It shows Launch only when nb_repository_url is set (layout.html L418-L420, launch.py L40), and adds each service only when that service is configured: Colab needs launch_buttons.colab_url (launch.py L124-L129).
Where this theme does it:
The notebook repository comes from project.github, and the only early return is a missing repo or page location (LaunchButton.tsx L15-L31).
The name is always derived as source plus suffix, unless launch_repo_url is set (launchUrls.ts L30-L43).
Five launch_* string options change the URL, and none turns the control off (template.yml L106-L123).
What the lecture repositories have (verified 2026-09-11)
Opt-in and explicit. Launch renders only when a notebook source is configured and at least one launch service is enabled. The theme stops guessing: the derivation from project.github, the .myst rule and launch_repo_suffix all go.
launch_repo_suffix is removed. All names are snake_case, like every other theme option.
Launch services are kept apart from the notebook source. The launch_notebook_* group says where the notebook lives; launch_colab and the future service keys say what can open it. One source serves every service, so a service is not a property of the notebook. With more than one service enabled, the control becomes a menu, and that needs no config change.
lecture-wasm loses its dead link at its next theme bump, with no config change.
lecture-python-programming's jb2 branch adds launch_notebook_repo and launch_colab: true to keep its Colab link.
Deferred: checking the notebook exists before Launch is shown
The maintainer wants a failsafe, so that Launch never opens a missing notebook. Where that check runs is not decided yet. Current thinking: an in-page script that shows Launch only when it finds the referenced notebook.
Approach
How it works
For
Against
In-page failsafe (current thinking)
Launch starts hidden. A script requests the page's notebook, for example HEAD https://raw.githubusercontent.com/<repo>/<branch>/<path>.ipynb, and reveals the control only on success. raw.githubusercontent.com allows cross-origin requests and returns 404 for a missing repository (checked 2026-09-11)
Accurate per page; catches a repository renamed or emptied after the build; no build change
One request to GitHub per page view (cacheable for the session); the control appears after load; readers without JavaScript, or where GitHub is blocked, never see it
Build-time check
The theme fetches the notebook repository's file list once per build, and renders Launch only on pages whose notebook is listed
Static, repeatable output; no requests from readers
Needs network during the build, and a GITHUB_TOKEN in CI (the unauthenticated GitHub API allows 60 requests an hour); goes stale if the repository changes after the build
Relies on Colab opening a notebook by URL (the claim in QuantEcon/quantecon-book-theme#359, not verified here), and on every site publishing its notebooks
Whichever approach is chosen:
Fail closed: hide the control on a timeout or error.
Keep the toolbar steady: no layout shift and no empty slot (the toolbar's optional slots use empty:hidden).
Decide per page.
Test the hidden state.
Acceptance criteria
Launch (desktop toolbar and mobile overflow menu) renders only when launch_notebook_repo is set and launch_colab is true. With either unset, there is no Launch control and no empty toolbar slot.
The Colab URL is built from launch_notebook_repo, launch_notebook_branch, launch_notebook_dir and launch_notebook_source_dir, and nothing is derived from project.github. launch_repo_suffix and the .myst rule are gone.
The options are declared in template.yml and listed in docs/configuration.md.
docs/launch.md and the README explain the options, map them from the Sphinx keys, and say that a site without a notebook source shows no Launch.
tests/unit/launch-urls.test.mjs covers the new options. The visual fixture sets launch_notebook_repo and launch_colab for the launch-colab test, and a new test asserts that no Launch control renders without them.
The CHANGELOG records the opt-in default and the renamed and removed options, as a breaking change for sites that relied on the guessed repository.
The deferred existence check is either implemented as decided above, or split into its own issue before this one closes.
After the release, live lecture-wasm shows no Launch link, and the jb2 build keeps its Colab link with the two new options.
Context
Source: the 2026-09-11 book-theme parity study, rows F073 (Google Colab launch link) and F076 (notebook repository mapping).
Out of scope (F076, latent, no lecture site affected): a sub-path inside a repository URL, and non-GitHub repository URLs, which the book theme warns about and skips (launch.py L51-L53).
Part of #147 (parity study 2026-09-11 — content correctness).
Revised in place 2026-09-11 after the maintainer review:
The revision is recorded in the comments.
Problem
The Launch control (in the desktop toolbar and the mobile overflow menu) appears on every page of any project that sets
project.github. It opens Colab on a notebook repository whose name the theme guesses: the source repository, minus any.mystsuffix, plus.notebooks. Onlylaunch_repo_urlorlaunch_repo_suffixoverride the guess, and no option hides the control. A site without a notebooks repository therefore links readers to Colab on a repository that does not exist. For example, lecture-wasm's/cobweb/openshttps://colab.research.google.com/github/QuantEcon/lecture-wasm.notebooks/blob/main/cobweb.ipynb, and that repository returns 404 (verified 2026-09-11).The book theme never guesses. It shows Launch only when
nb_repository_urlis set (layout.html L418-L420, launch.py L40), and adds each service only when that service is configured: Colab needslaunch_buttons.colab_url(launch.py L124-L129).Where this theme does it:
project.github, and the only early return is a missing repo or page location (LaunchButton.tsx L15-L31).launch_repo_urlis set (launchUrls.ts L30-L43).launch_*string options change the URL, and none turns the control off (template.yml L106-L123).What the lecture repositories have (verified 2026-09-11)
nb_repository_urlnb_repository_urlpoints at a 404The last row is fixed on the Sphinx side by QuantEcon/lecture-dp#60, QuantEcon/lecture-python.zh-cn#279 and QuantEcon/lecture-intro.zh-cn#305. Each removes the dead
nb_repository_url, following QuantEcon/lecture-python-programming.fa#145.Decision (2026-09-11)
Opt-in and explicit. Launch renders only when a notebook source is configured and at least one launch service is enabled. The theme stops guessing: the derivation from
project.github, the.mystrule andlaunch_repo_suffixall go.Flat option names now, shaped for nesting later. Theme options can only be
boolean,string,number,choiceorfile, in both the QuantEcon mystmd fork and upstream, so a nested block cannot be declared yet. Template options can only be scalars, so site templates pack lists and nested settings into YAML strings mystmd#112 asks for structured options. Each flat name is the future nested path with underscores, so the migration is mechanical:launch_notebook_repolaunch.notebook.repolaunch_repo_urlnb_repository_urllaunch_notebook_branch(defaultmain)launch.notebook.branchlaunch_branchnb_branchlaunch_notebook_dirlaunch.notebook.dirlaunch_notebooks_pathnb_path_to_notebookslaunch_notebook_source_dirlaunch.notebook.source_dirlaunch_source_pathpath_to_docslaunch_colablaunch.colablaunch_buttons.colab_urllaunch_notebook_url(future)launch.notebook.urllaunch_binderhub_url,launch_jupyterhub_url(future)launch.binderhub_url,launch.jupyterhub_urllaunch_buttons.binderhub_url,launch_buttons.jupyterhub_urllaunch_repo_suffixis removed. All names are snake_case, like every other theme option.Launch services are kept apart from the notebook source. The
launch_notebook_*group says where the notebook lives;launch_colaband the future service keys say what can open it. One source serves every service, so a service is not a property of the notebook. With more than one service enabled, the control becomes a menu, and that needs no config change.Migration. A lecture repository sets
launch_notebook_repoonly if that repository exists; the step is on the migration checklist (Lecture repos moving off the Sphinx theme have no checklist of what myst.yml and CI must now set #209).jb2branch addslaunch_notebook_repoandlaunch_colab: trueto keep its Colab link.Deferred: checking the notebook exists before Launch is shown
The maintainer wants a failsafe, so that Launch never opens a missing notebook. Where that check runs is not decided yet. Current thinking: an in-page script that shows Launch only when it finds the referenced notebook.
HEAD https://raw.githubusercontent.com/<repo>/<branch>/<path>.ipynb, and reveals the control only on success.raw.githubusercontent.comallows cross-origin requests and returns 404 for a missing repository (checked 2026-09-11)GITHUB_TOKENin CI (the unauthenticated GitHub API allows 60 requests an hour); goes stale if the repository changes after the buildWhichever approach is chosen:
empty:hidden).Acceptance criteria
launch_notebook_repois set andlaunch_colabis true. With either unset, there is no Launch control and no empty toolbar slot.launch_notebook_repo,launch_notebook_branch,launch_notebook_dirandlaunch_notebook_source_dir, and nothing is derived fromproject.github.launch_repo_suffixand the.mystrule are gone.template.ymland listed in docs/configuration.md.tests/unit/launch-urls.test.mjscovers the new options. The visual fixture setslaunch_notebook_repoandlaunch_colabfor thelaunch-colabtest, and a new test asserts that no Launch control renders without them.jb2build keeps its Colab link with the two new options.Context
hide_launch: the first version of this issue proposed an opt-out option besidehide_tocandhide_search. The hide_toc and hide_search options are declared and documented but have no effect #213 shows those two options have no effect, and opt-out keeps dead links as the default.server:backend, incl. localhost) #154 (Thebe server). All of them need a notebook source, which the options above provide.template.yml,app/types.ts, the docs andtheme.spec.ts, so whichever lands second rebases.