Skip to content

[spec] st.iframe - Embed content in an iframe#14373

Merged
lukasmasuch merged 14 commits intodevelopfrom
lukasmasuch/st-iframe-spec
Mar 20, 2026
Merged

[spec] st.iframe - Embed content in an iframe#14373
lukasmasuch merged 14 commits intodevelopfrom
lukasmasuch/st-iframe-spec

Conversation

@lukasmasuch
Copy link
Copy Markdown
Collaborator

@lukasmasuch lukasmasuch commented Mar 15, 2026

Describe your changes

Spec renderer: https://issues.streamlit.app/spec_renderer?pr=14373

Product spec for st.iframe — a new command to embed URLs, HTML content, or local HTML files in an iframe. Consolidates st.components.v1.iframe and st.components.v1.html into a single, discoverable API.

Key design decisions:

  • Single src parameter with auto-detection (URL vs HTML vs file path)
  • height="content" default with fallback to 400px for cross-origin URLs
  • Permissive sandbox policy matching existing component behavior
  • fullscreen permission enabled by default

GitHub Issue Link (if applicable)

Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@lukasmasuch lukasmasuch added the change:spec Issue contains a product or tech spec label Mar 15, 2026
@snyk-io
Copy link
Copy Markdown
Contributor

snyk-io bot commented Mar 15, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 15, 2026

Spec PR Validation

✅ All checks passed!

@lukasmasuch lukasmasuch marked this pull request as ready for review March 15, 2026 19:35
Copilot AI review requested due to automatic review settings March 15, 2026 19:35
@lukasmasuch lukasmasuch changed the title [spec] Add st.iframe product spec [spec] st.iframe - Embed content in an iframe Mar 15, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a product spec for a proposed new st.iframe command to embed URLs, HTML strings, or local HTML files via iframes, consolidating legacy st.components.v1.iframe + st.components.v1.html into a single API.

Changes:

  • Introduces a full product spec describing the proposed st.iframe API surface and behavior (input auto-detection, sizing, sandbox/permissions policy).
  • Documents migration guidance from st.components.v1.* and lists alternatives/future work.
  • Adds examples and an implementation checklist.

@lukasmasuch
Copy link
Copy Markdown
Collaborator Author

@cursor review

@lukasmasuch lukasmasuch mentioned this pull request Mar 15, 2026
2 tasks
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

lukasmasuch and others added 5 commits March 15, 2026 21:21
- Fix HTML detection description (fallback, not "detected by leading <")
- Reorder input detection: URL patterns checked before filesystem
- Add Windows path handling to detection rules
- Document srcdoc relative asset resolution limitations
- Correct permissions policy to reflect existing permissive defaults
- Add missing Mount import in Starlette example
- Clarify metrics naming (new "iframe" vs legacy "_iframe"/"_html")

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown
Collaborator

@jrieke jrieke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM! Agree that st.iframe is better than st.embed (I think with embed I'd think of embedding the app itself somewhere else).

My only point is whether we need the scrolling parameter – shouldn't this just work like st.container, where if it has fixed height and the content is longer, we automatically enable scrolling, otherwise not? I can't really see a use case for showing a very long page in a smaller iframe without enabling scrolling, or is there one? (If there is a use case for it, I'm also fine with including the scrolling parameter, but I think we'd need to think through the name so we make it congruent with possible vertical/horizontal scrolling options on st.container in the future).

```

The `st.components.v1.iframe` and `st.components.v1.html` functions will remain available
but should be documented as legacy APIs with migration guidance pointing to `st.iframe`.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we're officially deprecating them? I could go either way, but would be good to specify.

Copy link
Copy Markdown
Collaborator Author

@lukasmasuch lukasmasuch Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think we should deprecate them 👍 but maybe start with a soft deprecation (log + docstring). I will update the spec

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SG!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh we could also think about softly deprecating st.components.v1.html then and tell people to use st.html instead.

Comment on lines +373 to +374
[#4659](https://github.com/streamlit/streamlit/issues/4659) requests automatic height
adjustment for external URLs. True auto-height remains out of scope because:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the issue is actually only about auto-sizing when the input is a HTML string, which already seems to be resolved with the proposal here.


This would use CSS transforms to scale the iframe. Worth revisiting if demand grows.

### Folder Serving
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this is not out of scope since it's already resolved ;)

Copy link
Copy Markdown
Collaborator Author

@lukasmasuch lukasmasuch Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be pretty nice to just do st.iframe("path/to/a/folder") and it shows whatever static page is in there. But static serving and starlette already provide ways to do that, and there is also the st.serve idea which could play a role here.

@lukasmasuch
Copy link
Copy Markdown
Collaborator Author

lukasmasuch commented Mar 16, 2026

My only point is whether we need the scrolling parameter – shouldn't this just work like st.container, where if it has fixed height and the content is longer, we automatically enable scrolling, otherwise not?

If it's an external URL, we don't really know that. However, we could probably just always activate scrolling. But I'm not sure about the initial rationale for configuring scrolling as false in the old iframe.

On a related note, if we remove scrolling, it wouldn't be a 1-1 drop-in replacement anymore API-wise... but that might be fine.

lukasmasuch and others added 3 commits March 16, 2026 15:41
Soft deprecation includes docstring warnings and log messages,
with functions remaining fully functional.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@jrieke
Copy link
Copy Markdown
Collaborator

jrieke commented Mar 16, 2026

Ooooh, I wasn't even aware we had that scrolling parameter on st.components.v1.iframe :D

we could probably just always activate scrolling

Yeah that sounds right to me. I guess this only shows scrollbars if the content is actually longer, right?

Seems like for st.components.v1.html we also have the scrolling parameter (also set to False) but for st.html we didn't add it and didn't get any complaints as far as I can see. So probably OK to do the same here.

lukasmasuch and others added 3 commits March 16, 2026 15:46
- Remove incorrect reference to #4659 (that's about HTML content, now addressed)
- Update Related section to note #4659 is addressed by height="content"

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Move scrolling to out-of-scope since scrolling="auto" shows scrollbars
only when content overflows. Users can use CSS to hide if needed.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@lukasmasuch
Copy link
Copy Markdown
Collaborator Author

but for st.html we didn't add it and didn't get any complaints as far as I can see. So probably OK to do the same here.

to be fair, st.html doesn't even have height :) But I removed it for now from the default params in the spec

Copy link
Copy Markdown
Collaborator

@jrieke jrieke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be fair, st.html doesn't even have height

Haha, might be good to add at some point. Anyway, approved.

- HTML files (.html, .htm, .xhtml) continue to use srcdoc
- Other files (PDF, images, SVG, etc.) uploaded to media storage
- Browser's native viewers handle rendering
- No file type allowlist - unsupported types trigger download

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add data: prefix to URL detection patterns
- Add example showing data URL usage

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@lukasmasuch lukasmasuch merged commit af41d07 into develop Mar 20, 2026
30 checks passed
@lukasmasuch lukasmasuch deleted the lukasmasuch/st-iframe-spec branch March 20, 2026 09:26
lukasmasuch added a commit that referenced this pull request Mar 20, 2026
Implements st.iframe as specified in #14373, consolidating
st.components.v1.iframe and st.components.v1.html into a single,
discoverable command in the main namespace.

Features:
- Auto-detects input type: URL, Path object, existing file, or HTML string
- Supports absolute URLs (http/https/data:), relative URLs (/app/static/...)
- Embeds local HTML files via srcdoc, non-HTML files via media storage
- Width/height parameters with "stretch", "content", and pixel values
- tab_index parameter for accessibility/keyboard navigation

Closes #12977

Co-Authored-By: Claude Opus 4.6 <[email protected]>
lukasmasuch added a commit that referenced this pull request Mar 27, 2026
## Describe your changes

Implements `st.iframe` as specified in
[#14373](#14373),
consolidating `st.components.v1.iframe` and `st.components.v1.html` into
a single, discoverable command in the main Streamlit namespace.

**Features:**
- Auto-detects input type: URL, Path object, existing file, or HTML
string
- Supports absolute URLs (`http://`, `https://`, `data:`), relative URLs
(`/app/static/...`)
- Embeds local HTML files via `srcdoc`, non-HTML files via media storage
- `width`/`height` parameters with `"stretch"`, `"content"`, and pixel
values
- `height="content"` auto-sizes to content for srcdoc (falls back to
400px for URLs)
- `width="content"` auto-sizes to content for srcdoc (falls back to
stretch for URLs)
- Uses standard `widthConfig`/`heightConfig` layout system (no custom
proto fields)
- `tab_index` parameter for accessibility/keyboard navigation

**Usage:**
```python
import streamlit as st
from pathlib import Path

# Embed a URL
st.iframe("https://docs.streamlit.io", height=600)

# Embed HTML content with auto-sizing
st.iframe("<h1>Hello World</h1>")  # height="content" by default

# Embed a local HTML file
st.iframe(Path("reports/dashboard.html"), height=800)

# Embed a PDF
st.iframe(Path("documents/manual.pdf"), height=600)

# Auto-size both width and height
st.iframe("<div style='width:200px'>Content</div>", width="content", height="content")
```

## GitHub Issue Link (if applicable)

- Closes #12977

## Testing Plan

- [x] Unit Tests (Python) - 42 tests covering URL handling, HTML string
detection, local file handling, dimension parameters, tab_index
validation, width/height content sizing
- [x] Unit Tests (Frontend) - 27 tests covering rendering, auto-sizing
behavior, message validation
- [x] E2E Tests (Playwright) - 10 tests covering rendering, content
verification, sandbox policy, auto-sizing
- [x] Typing Tests (mypy) - Parameter and return type validation

<!-- agent-metrics-start -->
<details>
<summary>Agent metrics</summary>

| Type | Name | Count |
|------|------|------:|
| skill | checking-changes | 6 |
| skill | debugging-streamlit | 1 |
| skill | finalizing-pr | 3 |
| skill | fixing-pr | 2 |
| skill | implementing-feature | 1 |
| skill | updating-internal-docs | 4 |
| subagent | fixing-pr | 6 |
| subagent | general-purpose | 19 |
| subagent | reviewing-local-changes | 4 |
| subagent | simplifying-local-changes | 4 |

</details>
<!-- agent-metrics-end -->

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Streamlit Bot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:spec Issue contains a product or tech spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants