Description
When running Textual-Serve bound to 0.0.0.0, the landing‐page template inlines all static asset URLs (CSS/JS/images) using the configured host or public_url. If you pass host="0.0.0.0" (or forget to set public_url), every request for /static/... goes to http://0.0.0.0:8000/static/..., which is not routable, and assets fail to load.
Steps to Reproduce
- Install
textual-serve==1.1.2 in a project.
- Create a
main.py containing:
from textual_serve.server import Server
server = Server("python3 your_app.py", host="0.0.0.0")
server.serve(debug=True)
- Run:
- Open a browser to
http://<your-machine-IP>:8000/.
- Observe in DevTools → Network that requests for
xterm.css, textual.js, etc. are targeting http://0.0.0.0:8000/static/... and failing.
Actual Behavior
- Asset requests are issued to
0.0.0.0:8000, which refuses connections.
- Landing page shows placeholder panel without styling or “Run ▶︎” button (static assets never load).
Expected Behavior
Assets should either:
- Be served via relative URLs (e.g.
/static/js/textual.js) so they load from the same origin the browser requested, or
- If an absolute URL is required, fall back to using the incoming
Host header when public_url is unset, rather than the bind address.
Environment
- textual-serve version:
1.1.2
- Python:
3.10.11
- Platform: Ubuntu 22.04 LTS (Docker container)
- Browser: Chrome 135.0.0.0 on macOS 10.15.7
Proposed Solution
Update the Jinja template (app_index.html) so that static assets use relative paths by default:
<!-- before -->
<link rel="stylesheet" href="{{ config.static.root }}/css/xterm.css">
<!-- after -->
<link rel="stylesheet" href="/static/css/xterm.css">
Alternatively, detect when public_url is the generic bind address (0.0.0.0 or ::) and fall back to Host header–based URL generation.
Description
When running Textual-Serve bound to
0.0.0.0, the landing‐page template inlines all static asset URLs (CSS/JS/images) using the configuredhostorpublic_url. If you passhost="0.0.0.0"(or forget to setpublic_url), every request for/static/...goes tohttp://0.0.0.0:8000/static/..., which is not routable, and assets fail to load.Steps to Reproduce
textual-serve==1.1.2in a project.main.pycontaining:http://<your-machine-IP>:8000/.xterm.css,textual.js, etc. are targetinghttp://0.0.0.0:8000/static/...and failing.Actual Behavior
0.0.0.0:8000, which refuses connections.Expected Behavior
Assets should either:
/static/js/textual.js) so they load from the same origin the browser requested, orHostheader whenpublic_urlis unset, rather than the bind address.Environment
1.1.23.10.11Proposed Solution
Update the Jinja template (
app_index.html) so that static assets use relative paths by default:Alternatively, detect when
public_urlis the generic bind address (0.0.0.0or::) and fall back toHostheader–based URL generation.