fix(desktop): embed and serve CSS/JS assets so the wry build renders styled #64

Merged
nrupard merged 1 commit from fix/VAPP-53-desktop-embedded-css-assets into main 2026-06-29 21:50:38 +02:00
Owner

What

Fixes the desktop (wry) build rendering unstyled: Tailwind + theme CSS were not applied in the desktop webview while the web build looked correct.

Root cause

The dioxus-asset-resolver resolves asset!-referenced files from a sibling assets/ dir next to the running binary at runtime. The CI desktop artifact ships only the executable (the workflow extracts just target/dx/vervain-app/release/linux/app/vervain-app, no assets/ dir), so every stylesheet URL 404d and the app rendered with no CSS. The EMBEDDED_ASSETS (include_dir) static was declared with a "renders styled without a sibling assets dir" comment but was never referenced - dead code that never served anything.

Fix

Wire EMBEDDED_ASSETS exactly the way yotun's desktop build already does (same dioxus 0.7.7, same include_dir 0.7):

  • Register a wry use_asset_handler("assets", ...) in App that serves every /assets/<file> request out of the binary-embedded EMBEDDED_ASSETS dir. The desktop protocol dispatcher matches by first path segment, so this handler runs ahead of the filesystem-based resolver fallback.
  • Add an embedded_asset_mime helper to set Content-Type from the file extension.
  • On desktop, the root stylesheets (tailwind-built.css, main.css in main.rs) and the vendored xterm bundle (xterm.css/xterm.js/addon-fit.js in terminal.rs) now use literal /assets/... hrefs that hit the handler. Web/server builds keep the hashing asset! pipeline unchanged via #[cfg(not(feature = "desktop"))].

The binary is now self-contained: a bare vervain-app renders fully styled with no sibling assets/ dir and makes no external request for its own CSS/JS.

Verification

Run in ghcr.io/niceguyit/rust-builder-glibc:v1.0.1-rust1.94-trixie (the same image the desktop Dockerfile builds in):

  • cargo fmt --check clean.
  • cargo clippy --features desktop --all-targets -- -D warnings clean (this is the new code path; note just check only compiles the server + wasm features, so the desktop cfg blocks are not covered by the standard check).
  • cargo clippy --all-targets --features server -- -D warnings clean and cargo check --target wasm32-unknown-unknown clean - no regression to the web path.

End-to-end visual confirmation (the styled window) requires running the built desktop binary on a real display, same as yotun; the asset-serving code is byte-for-byte the proven yotun pattern.

#VAPP-53

## What Fixes the desktop (wry) build rendering unstyled: Tailwind + theme CSS were not applied in the desktop webview while the web build looked correct. ## Root cause The `dioxus-asset-resolver` resolves `asset!`-referenced files from a sibling `assets/` dir next to the running binary at runtime. The CI desktop artifact ships only the executable (the workflow extracts just `target/dx/vervain-app/release/linux/app/vervain-app`, no `assets/` dir), so every stylesheet URL 404d and the app rendered with no CSS. The `EMBEDDED_ASSETS` (`include_dir`) static was declared with a "renders styled without a sibling assets dir" comment but was never referenced - dead code that never served anything. ## Fix Wire `EMBEDDED_ASSETS` exactly the way yotun's desktop build already does (same dioxus 0.7.7, same `include_dir` 0.7): - Register a wry `use_asset_handler("assets", ...)` in `App` that serves every `/assets/<file>` request out of the binary-embedded `EMBEDDED_ASSETS` dir. The desktop protocol dispatcher matches by first path segment, so this handler runs ahead of the filesystem-based resolver fallback. - Add an `embedded_asset_mime` helper to set `Content-Type` from the file extension. - On desktop, the root stylesheets (`tailwind-built.css`, `main.css` in `main.rs`) and the vendored xterm bundle (`xterm.css`/`xterm.js`/`addon-fit.js` in `terminal.rs`) now use literal `/assets/...` hrefs that hit the handler. Web/server builds keep the hashing `asset!` pipeline unchanged via `#[cfg(not(feature = "desktop"))]`. The binary is now self-contained: a bare `vervain-app` renders fully styled with no sibling `assets/` dir and makes no external request for its own CSS/JS. ## Verification Run in `ghcr.io/niceguyit/rust-builder-glibc:v1.0.1-rust1.94-trixie` (the same image the desktop Dockerfile builds in): - `cargo fmt --check` clean. - `cargo clippy --features desktop --all-targets -- -D warnings` clean (this is the new code path; note `just check` only compiles the `server` + wasm features, so the desktop cfg blocks are not covered by the standard check). - `cargo clippy --all-targets --features server -- -D warnings` clean and `cargo check --target wasm32-unknown-unknown` clean - no regression to the web path. End-to-end visual confirmation (the styled window) requires running the built desktop binary on a real display, same as yotun; the asset-serving code is byte-for-byte the proven yotun pattern. #VAPP-53
fix(desktop): embed and serve CSS/JS assets so the wry build renders styled
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 31s
Create release / Create release from merged PR (pull_request) Has been skipped
41a689e294
The desktop (wry) build rendered unstyled: the dioxus-asset-resolver
looks for asset files next to the running binary at runtime, but the CI
artifact ships only the executable (no sibling `assets/` dir), so every
`asset!`-referenced stylesheet 404d and the app rendered without Tailwind
or theme CSS. The already-declared `EMBEDDED_ASSETS` (`include_dir`) was
dead code, never wired to serve those bytes.

Wire it the same way yotun's desktop build does: register a wry
`use_asset_handler("assets", ...)` in `App` that serves every
`/assets/<file>` request out of the binary-embedded `EMBEDDED_ASSETS`
dir, ahead of the filesystem-based resolver fallback. On desktop the root
stylesheets (`tailwind-built.css`, `main.css`) and the vendored xterm
bundle (`terminal.rs`) now use literal `/assets/...` hrefs that hit the
handler; web/server builds keep the hashing `asset!` pipeline unchanged.

The binary is now self-contained: a bare `vervain-app` install renders
fully styled with no sibling `assets/` dir and makes no external request
for its own CSS/JS.

Verified in the rust-builder-glibc image (the same image the desktop
Dockerfile builds in): cargo fmt clean, `cargo clippy --features desktop
--all-targets -D warnings` clean, and the server clippy + wasm checks
still pass with no regression to the web path.

#VAPP-53

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard deleted branch fix/VAPP-53-desktop-embedded-css-assets 2026-06-29 21:50:38 +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!64
No description provided.