Skip to content

Feature request: optionally honor the isolated output metadata by sandboxing text/html outputs in an iframe (static HTML build)Β #717

@shimwell

Description

@shimwell

Hi, and thank you so much for MyST-NB β€” it's been wonderful to work with, and the executable-docs workflow is exactly what we were hoping for. πŸ™

I have a small feature request, and I fully apologise if I've simply missed an existing option or am misunderstanding something β€” please point me at the docs if so.

Summary

Would the maintainers consider (optionally) honoring the isolated output metadata when rendering text/html outputs in the static HTML build β€” i.e. emitting the output inside a sandboxed iframe (e.g. <iframe srcdoc="…">) rather than inlining it?

Background / current behavior

Some libraries' rich reprs return a full, standalone HTML document (<!DOCTYPE html><html>…</html>) and signal β€” via the isolated output metadata β€” that it should be rendered in isolation. The live Jupyter Notebook frontends honor this by sandboxing the output in an iframe, so the full document renders correctly.

When the same notebook is built with MyST-NB, the text/html output appears to be inlined regardless of the isolated flag. For a full-document repr this produces a nested <!DOCTYPE html>/<html> inside the page <body>, which is invalid HTML and doesn't render reliably.

Minimal reproducible example

conf.py:

extensions = ["myst_nb"]
nb_execution_mode = "force"

index.md:

---
file_format: mystnb
kernelspec:
  name: python3
  display_name: Python 3
---

# Isolated HTML output demo

```{code-cell} python
class FullDocViewer:
    """A rich repr that returns a *full* standalone HTML document and asks,
    via the `isolated` metadata, for it to be rendered in isolation."""
    def _repr_mimebundle_(self, include=None, exclude=None):
        html = (
            "<!DOCTYPE html><html><head><meta charset='utf-8'><title>demo</title>"
            "<style>body { background: #eef; }</style></head>"
            "<body><h1>Hello from an isolated document</h1></body></html>"
        )
        return {"text/html": html}, {"text/html": {"isolated": True}}

FullDocViewer()
```

Build:

sphinx-build -b html . _build/html

Observed: _build/html/index.html contains the full document inlined β€” there are two <!DOCTYPE html> in one page, and the isolated flag is ignored.

Hoped-for: the output is rendered in a sandboxed iframe (e.g. <iframe srcdoc="…">), matching how the classic Notebook frontend treats isolated outputs, so full-document HTML reprs display correctly in the built docs.

Possible approaches (just ideas β€” you'll know far better)

  • Honor {"text/html": {"isolated": true}} (or the top-level isolated metadata) by wrapping the HTML in an <iframe srcdoc="…">; or
  • A config flag (e.g. nb_render_html_isolated = True) for projects that want this opt-in.

Related issues (not duplicates)

#54 and #436 cover interactive fragments (Plotly/Bokeh/HoloViews emit <div> + <script> that inline fine once JS loading is handled). This request is specifically about outputs that are a full standalone HTML document and rely on the isolated convention β€” a different case that iframe-sandboxing would solve.

Why it matters to us

We maintain a small simulation library whose interactive viewer is a self-contained HTML document; it renders perfectly in Jupyter but we can't currently embed it in our MyST-NB docs without falling back to manually generating files and hand-writing iframes.

Environment

  • myst-nb 1.4.0 (latest)
  • sphinx 9.1.0
  • myst-parser 5.1.0
  • nbclient 0.10.4
  • docutils 0.22.4
  • Python 3.13.3

I completely understand if this is out of scope or intentionally left to the frontend β€” and I'm very happy to attempt a PR with a little guidance if you'd welcome one. Thank you again for the project and for considering this. πŸ™

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions