jerpint / jerpint/woltspace

Unified iframe serving for sites and projects

Open
#233 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
12
Forks
1
Avg merge
7h 13m
Merged PRs (30d)
31

Description

Problem

Both sites (/wolt/{name}/site/) and projects (/project/{name}/) proxy through the FastAPI server via httpx. This causes:

  • Broken links in projects (#212): Frameworks (Astro, Next, etc.) generate absolute root-relative paths (/blog, /@vite/client, /favicon.svg). The proxy strips the /project/{name}/ prefix before forwarding, but the response HTML still references root paths. Browser resolves these against the woltspace host → 404s everywhere.
  • Unnecessary complexity in sites: The proxy strips livereload's native WebSocket script and injects a custom one routed through /wolt/{name}/site/livereload, plus a dedicated WebSocket relay endpoint. ~40 lines of script rewriting + a full WS relay, just because the iframe loads the proxy URL instead of the port directly.

Sites work today only by luck — simple static files with relative links. Any site using absolute paths would break the same way projects do.

Root cause

Every service (site or project) already runs on its own port (livereload or dev server). The proxy exists to give a stable URL through the main server, but it's the proxy that breaks link resolution.

Proposed fix: iframe-to-port

Instead of proxying request/response through the server, serve everything via iframes pointed directly at localhost:PORT.

Viewport (developing):

  • split.html iframe → localhost:PORT (instead of /project/blog/ or /wolt/uxwolt/site/)
  • Links resolve naturally against root — no rewriting needed
  • Livereload's native script works as-is — no custom WS relay needed

Public/tunnel access (sharing):

  • /project/{name}/ and /wolt/{name}/site/ return a thin iframe wrapper page:
    <!DOCTYPE html>
    <html><head><style>body{margin:0}iframe{width:100%;height:100vh;border:none}</style></head>
    <body><iframe src="http://localhost:PORT/"></iframe></body></html>
    
  • One tunnel (port 7777), zero rewriting, links work inside the iframe
  • Static dist/ serving (strategy 2) stays as-is — no link issues for built sites

What gets deleted:

  • httpx proxy logic in serve_project() (strategy 1) — replaced by iframe wrapper
  • httpx proxy logic in serve_wolt_site() — replaced by iframe wrapper
  • Livereload script stripping + injection (app.py ~lines 856-876)
  • Custom WebSocket relay endpoint /wolt/{name}/site/livereload (app.py ~lines 896+)
  • x-frame-options / content-security-policy header stripping (no longer needed — iframe is same-origin)

What stays:

  • Static file serving from dist/ (strategy 2) and project root (strategy 3)
  • Project start/stop, port allocation, state management — all unchanged
  • Site auto-start on session creation — unchanged

The unified model

site or project runs on localhost:PORT
        │
        ├── viewport iframe → localhost:PORT (developing)
        └── /project/{name}/ or /wolt/{name}/site/ → iframe wrapper page (sharing via tunnel)

Same architecture for sites and projects. Clone any repo, add woltspace.json, start, iframe serves it. Zero code modifications to the project.

Impact

  • Fixes #212 (project proxy link rewriting)
  • Simplifies site serving (delete ~60 lines of proxy + WS relay)
  • Unblocks "clone any GitHub repo and serve it" workflow
  • No breaking changes to sites — they keep working, just simpler
  • No changes to project lifecycle (start/stop/discover)

Out of scope

  • Subdomain-per-project routing (future, if needed for cookie isolation)
  • GitHub clone UX improvements (separate issue)
  • Project gallery / marketplace (#220)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with split.html and app.py, especially serve_project(), serve_wolt_site(), the livereload handling around lines 856-876, and the WebSocket relay around line 896. Trace the existing project and site serving strategies before changing them; done means both viewport and sharing paths use iframe-to-port serving, while static serving and lifecycle behavior remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
fastapi, python
Domain
backend, web-dev
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.