fix(shell): bound Outlet in SuspenseBoundary so navigation stops flashing #82

Merged
Claude-Run merged 1 commit from fix/VAPP-37-suspense-boundary-shell-flash into main 2026-07-04 17:55:56 +02:00
Member

Every sidebar page fetches its data with use_server_future(...)?, which suspends the page component while the server-fn POST is in flight. The content-pane Outlet in layout.rs had no SuspenseBoundary above it (and none existed anywhere in the tree), so that suspense unwound to the root: while the POST was pending the whole shell (sidebar, topbar, statusbar, content) left the DOM and re-painted on resolve, which read as a full-screen flash on every navigation. Root cause is page-level suspense with no boundary, not a redirect bounce, shell remount, or style recalc.

Wrap the Outlet in a SuspenseBoundary (inside an ErrorBoundary) at the content pane so a page's suspense, or a failing server fn, is caught there: only this pane shows a Loading… placeholder while the POST is in flight and the shell stays painted. The redirect use_effect (layout.rs) is untouched, so NeedsFirstUser -> /setup and missing-session -> /login behavior is unchanged. The fix is framework-level and applies to both the web (wasm) and wry desktop targets.

Add layout_guard.rs, a compile-time test that fails if the SuspenseBoundary/ErrorBoundary/Outlet trio disappears from layout.rs, so the boundary cannot silently regress.

#VAPP-37

Every sidebar page fetches its data with `use_server_future(...)?`, which suspends the page component while the server-fn POST is in flight. The content-pane `Outlet` in `layout.rs` had no `SuspenseBoundary` above it (and none existed anywhere in the tree), so that suspense unwound to the root: while the POST was pending the whole shell (sidebar, topbar, statusbar, content) left the DOM and re-painted on resolve, which read as a full-screen flash on every navigation. Root cause is page-level suspense with no boundary, not a redirect bounce, shell remount, or style recalc. Wrap the `Outlet` in a `SuspenseBoundary` (inside an `ErrorBoundary`) at the content pane so a page's suspense, or a failing server fn, is caught there: only this pane shows a `Loading…` placeholder while the POST is in flight and the shell stays painted. The redirect `use_effect` (`layout.rs`) is untouched, so `NeedsFirstUser` -> `/setup` and missing-session -> `/login` behavior is unchanged. The fix is framework-level and applies to both the web (wasm) and wry desktop targets. Add `layout_guard.rs`, a compile-time test that fails if the `SuspenseBoundary`/`ErrorBoundary`/`Outlet` trio disappears from `layout.rs`, so the boundary cannot silently regress. #VAPP-37
fix(shell): bound Outlet in SuspenseBoundary so navigation stops flashing
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 30s
Create release / Create release from merged PR (pull_request) Has been skipped
a75f8c52b6
Every sidebar page fetches its data with `use_server_future(...)?`, which suspends the page component while the server-fn POST is in flight. The content-pane `Outlet` in `layout.rs` had no `SuspenseBoundary` above it (and none existed anywhere in the tree), so that suspense unwound to the root: while the POST was pending the whole shell (sidebar, topbar, statusbar, content) left the DOM and re-painted on resolve, which read as a full-screen flash on every navigation. Root cause is page-level suspense with no boundary, not a redirect bounce, shell remount, or style recalc.

Wrap the `Outlet` in a `SuspenseBoundary` (inside an `ErrorBoundary`) at the content pane so a page's suspense, or a failing server fn, is caught there: only this pane shows a `Loading…` placeholder while the POST is in flight and the shell stays painted. The redirect `use_effect` (`layout.rs`) is untouched, so `NeedsFirstUser` -> `/setup` and missing-session -> `/login` behavior is unchanged. The fix is framework-level and applies to both the web (wasm) and wry desktop targets.

Add `layout_guard.rs`, a compile-time test that fails if the `SuspenseBoundary`/`ErrorBoundary`/`Outlet` trio disappears from `layout.rs`, so the boundary cannot silently regress.

#VAPP-37
Claude-Run deleted branch fix/VAPP-37-suspense-boundary-shell-flash 2026-07-04 17:55:56 +02:00
Sign in to join this conversation.
No reviewers
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
psa-systems/vervain-apps!82
No description provided.