[nu-demo] Biz island iframe missing /ui/ in src — renders blank in OS shell #179

Closed
opened 2026-04-24 22:34:03 +00:00 by mik-tf · 1 comment
Owner

Symptom

Clicking the Biz island in the herodemo dock loads an empty iframe — no
sidebar, no main content, just a blank page. All other islands (Office, Books,
Voice, OSIS, Collab, etc.) render normally.

Root cause

hero_os_app/src/island_content.rs:398 registers Biz with the wrong iframe src:

"biz" => rsx! { ExternalServiceIframe { src: "/hero_biz/", id: "biz-iframe" } },

Every other island uses /hero_<svc>/ui/:

"books" => rsx! { ExternalServiceIframe { src: "/hero_books/ui/", id: "books-iframe" } },
"collab" => rsx! { ExternalServiceIframe { src: "/hero_collab/ui/", id: "collab-iframe" } },
"slides" => rsx! { ExternalServiceIframe { src: "/hero_slides/ui/", id: "slides-iframe" } },
"whiteboard" => rsx! { ExternalServiceIframe { src: "/hero_whiteboard/ui/", id: "whiteboard-iframe" } },
"browser-mcp" => rsx! { ExternalServiceIframe { src: "/hero_browser/ui/", id: "browser-mcp-iframe" } },
"osis" => rsx! { ExternalServiceIframe { src: "/hero_osis/ui/", id: "osis-iframe" } },

The src /hero_biz/ makes hero_router behave as follows:

GET /hero_biz/    → 308  Location: /hero_biz       (router strips trailing slash)
GET /hero_biz     → 404  (no service-root handler — only /hero_biz/ui and /hero_biz/rpc are routed)

So the iframe ends up at a 404 page, which renders as blank.

When pointed correctly at /hero_biz/ui/, hero_router proxies to the
hero_biz_ui socket, which:

GET /hero_biz/ui/  → 308  Location: /hero_biz/ui
GET /hero_biz/ui   → 303  Location: /hero_biz/ui/c/<default_context>   (index_redirect)
GET /hero_biz/ui/c/threefold → 200 + Dashboard HTML (78 KB)

Fix

One-line change to hero_os_app/src/island_content.rs:

- "biz" => rsx! { ExternalServiceIframe { src: "/hero_biz/", id: "biz-iframe" } },
+ "biz" => rsx! { ExternalServiceIframe { src: "/hero_biz/ui/", id: "biz-iframe" } },

Verified live

Patched on herodemo and rebuilt the WASM shell. Biz iframe now loads to
/hero_biz/ui/c/<default_context> and renders the dashboard with sidebar,
top-bar, persons/companies/contracts navigation.

Why this regression existed

Likely artifact of an early bring-up when hero_biz was being routed via
/hero_biz/* directly rather than the /hero_<svc>/<sock> convention that
hero_router enforces today. The other islands were updated when the convention
landed; Biz was missed.

Tests / hardening

  • Regression test: in hero_os_app, add a unit test asserting every
    ExternalServiceIframe registration ends with /ui/ (or matches a
    sanctioned shape).
  • WASM smoke: Hero Browser MCP test that opens each archipelago island
    and asserts non-empty body/sidebar within 3s.
  • Doc: add to the per-archipelago island registration checklist that
    the iframe src must use /hero_<name>/ui/ (or use a typed builder).
  • home#171 — dock islands web-feature gaps (companion class)
  • home#160 — consolidated demo state

Signed-off-by: mik-tf

## Symptom Clicking the **Biz** island in the herodemo dock loads an empty iframe — no sidebar, no main content, just a blank page. All other islands (Office, Books, Voice, OSIS, Collab, etc.) render normally. ## Root cause `hero_os_app/src/island_content.rs:398` registers Biz with the wrong iframe src: ```rust "biz" => rsx! { ExternalServiceIframe { src: "/hero_biz/", id: "biz-iframe" } }, ``` Every other island uses `/hero_<svc>/ui/`: ```rust "books" => rsx! { ExternalServiceIframe { src: "/hero_books/ui/", id: "books-iframe" } }, "collab" => rsx! { ExternalServiceIframe { src: "/hero_collab/ui/", id: "collab-iframe" } }, "slides" => rsx! { ExternalServiceIframe { src: "/hero_slides/ui/", id: "slides-iframe" } }, "whiteboard" => rsx! { ExternalServiceIframe { src: "/hero_whiteboard/ui/", id: "whiteboard-iframe" } }, "browser-mcp" => rsx! { ExternalServiceIframe { src: "/hero_browser/ui/", id: "browser-mcp-iframe" } }, "osis" => rsx! { ExternalServiceIframe { src: "/hero_osis/ui/", id: "osis-iframe" } }, ``` The src `/hero_biz/` makes hero_router behave as follows: ``` GET /hero_biz/ → 308 Location: /hero_biz (router strips trailing slash) GET /hero_biz → 404 (no service-root handler — only /hero_biz/ui and /hero_biz/rpc are routed) ``` So the iframe ends up at a 404 page, which renders as blank. When pointed correctly at `/hero_biz/ui/`, hero_router proxies to the `hero_biz_ui` socket, which: ``` GET /hero_biz/ui/ → 308 Location: /hero_biz/ui GET /hero_biz/ui → 303 Location: /hero_biz/ui/c/<default_context> (index_redirect) GET /hero_biz/ui/c/threefold → 200 + Dashboard HTML (78 KB) ``` ## Fix One-line change to `hero_os_app/src/island_content.rs`: ```diff - "biz" => rsx! { ExternalServiceIframe { src: "/hero_biz/", id: "biz-iframe" } }, + "biz" => rsx! { ExternalServiceIframe { src: "/hero_biz/ui/", id: "biz-iframe" } }, ``` ## Verified live Patched on herodemo and rebuilt the WASM shell. Biz iframe now loads to `/hero_biz/ui/c/<default_context>` and renders the dashboard with sidebar, top-bar, persons/companies/contracts navigation. ## Why this regression existed Likely artifact of an early bring-up when hero_biz was being routed via `/hero_biz/*` directly rather than the `/hero_<svc>/<sock>` convention that hero_router enforces today. The other islands were updated when the convention landed; Biz was missed. ## Tests / hardening - [ ] **Regression test**: in `hero_os_app`, add a unit test asserting every `ExternalServiceIframe` registration ends with `/ui/` (or matches a sanctioned shape). - [ ] **WASM smoke**: Hero Browser MCP test that opens each archipelago island and asserts non-empty body/sidebar within 3s. - [ ] **Doc**: add to the per-archipelago island registration checklist that the iframe src must use `/hero_<name>/ui/` (or use a typed builder). ## Related - [home#171](https://forge.ourworld.tf/lhumina_code/home/issues/171) — dock islands web-feature gaps (companion class) - [home#160](https://forge.ourworld.tf/lhumina_code/home/issues/160) — consolidated demo state Signed-off-by: mik-tf
Author
Owner

Fixed in hero_os commit 000922b (fix(islands): Biz iframe src missing /ui/ — page rendered blank (#179)).

Verification at crates/hero_os_app/src/island_content.rs:398:

"biz" => rsx! { ExternalServiceIframe { src: "/hero_biz/ui/", id: "biz-iframe" } },

This matches the /hero_<svc>/ui/ pattern used by every sibling island (books, collab, slides, whiteboard, browser-mcp, osis), so hero_router proxies correctly to the hero_biz_ui socket instead of returning 404.

Deployed in v0.x.x-dev to herodemo.gent01.grid.tf during the home#180 work and visually confirmed (Biz island now renders sidebar + main content).

Signed-off-by: mik-tf

Fixed in hero_os commit 000922b (`fix(islands): Biz iframe src missing /ui/ — page rendered blank (#179)`). Verification at `crates/hero_os_app/src/island_content.rs:398`: ```rust "biz" => rsx! { ExternalServiceIframe { src: "/hero_biz/ui/", id: "biz-iframe" } }, ``` This matches the `/hero_<svc>/ui/` pattern used by every sibling island (books, collab, slides, whiteboard, browser-mcp, osis), so hero_router proxies correctly to the `hero_biz_ui` socket instead of returning 404. Deployed in v0.x.x-dev to herodemo.gent01.grid.tf during the home#180 work and visually confirmed (Biz island now renders sidebar + main content). Signed-off-by: mik-tf
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/home#179
No description provided.