Fix blank /web UI and /api route under the bundled server

The Flutter web bundle was built with the default base href of "/" but is
served under "/web/", so index.html loaded while every asset reference
resolved to the site root and 404'd, leaving a blank page. Build the bundle
with --base-href=/web/ so asset URLs match the mount point.

Also correct the root guidance text (the API explorer is at /api/docs, not
/api) and add an /api -> /api/docs redirect for convenience.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
rzuasti
2026-06-06 12:25:07 -04:00
co-authored by Claude Opus 4.8
parent d5d5ffa455
commit cf8979f63d
3 changed files with 16 additions and 3 deletions
+6 -1
View File
@@ -1,12 +1,14 @@
# OOTT ToDo list # OOTT ToDo list
- [ ] Add support for push notifications to the app (iOS and Android) - [ ] Add support for push notifications to the app (iOS and Android)
- [ ] Modify the release script to check that gh is logged in and that frontend tests are run before releasing
- [x] README.md - Add section about securing access (reverse proxy, never expose to the internet, etc.) - [x] README.md - Add section about securing access (reverse proxy, never expose to the internet, etc.)
- [x] README.md - Simplify storage section (remove the calculations - just leave the results) - [x] README.md - Simplify storage section (remove the calculations - just leave the results)
## Release plan for 0.2.0 ## Release plan for 0.2.0
- [x] Test Android UI on emulator - [x] Test Android UI on emulator
- [ ] Release 0.1.0 - [x] Release 0.1.0
- [ ] Fix bugs and release 0.1.1
- [ ] Install in test server (docker) following documented process - [ ] Install in test server (docker) following documented process
- [ ] Install test app on iPhone - [ ] Install test app on iPhone
- [ ] Test in-house for 1 week - [ ] Test in-house for 1 week
@@ -20,11 +22,14 @@
## Backend ## Backend
- [ ] In notifications, when the vendor is empty put (unknown)
- [x] In the active scanners status, it should count the number of distinct devices it saw on the last scan (avoid duplicates) - [x] In the active scanners status, it should count the number of distinct devices it saw on the last scan (avoid duplicates)
- [ ] Implement the pushover API call directly to support HTML content and review notification text to use it - [ ] Implement the pushover API call directly to support HTML content and review notification text to use it
## Frontend ## Frontend
- [ ] When the user goes to the / URI in a production server redirect him to /web
- [ ] Add a link to the API docs (/api/docs) in the navigation (new window - only visible in wide)
- [x] Review the whole codebase for dead code, duplication and simplicity - [x] Review the whole codebase for dead code, duplication and simplicity
- [x] In the devices list, add an order by type (in the wide version it should be over the icon on the left of the list) - [x] In the devices list, add an order by type (in the wide version it should be over the icon on the left of the list)
- [x] How expensive it is to get the total number of pages and implement a go to last page - [x] How expensive it is to get the total number of pages and implement a go to last page
+4 -2
View File
@@ -13,7 +13,7 @@ use axum::Json;
use axum::extract::Request; use axum::extract::Request;
use axum::http::StatusCode; use axum::http::StatusCode;
use axum::middleware::Next; use axum::middleware::Next;
use axum::response::Response; use axum::response::{Redirect, Response};
use axum::routing::{delete, get, post, put}; use axum::routing::{delete, get, post, put};
use axum::{Router, http}; use axum::{Router, http};
use log::{debug, error, info}; use log::{debug, error, info};
@@ -170,8 +170,10 @@ pub async fn serve() -> Result<(), Box<dyn Error>> {
.layer(ServiceBuilder::new().layer(cors_layer)) .layer(ServiceBuilder::new().layer(cors_layer))
.route( .route(
"/", "/",
get(|| async { "Go to /web for the UI or to /api for the better UI." }), get(|| async { "Go to /web for the UI or to /api/docs for the API explorer." }),
) )
// The API explorer lives at /api/docs; redirect the bare /api for convenience.
.route("/api", get(|| async { Redirect::temporary("/api/docs") }))
.nest_service("/web", static_files) .nest_service("/web", static_files)
.merge(SwaggerUi::new("/api/docs").url("/api/docs/openapi.json", ApiDoc::openapi())); .merge(SwaggerUi::new("/api/docs").url("/api/docs/openapi.json", ApiDoc::openapi()));
+6
View File
@@ -18,4 +18,10 @@ in
# Build the web bundle (the backend serves these assets). # Build the web bundle (the backend serves these assets).
targetFlutterPlatform = "web"; targetFlutterPlatform = "web";
# The backend serves these assets under `/web/` (see web_server::serve), so
# the bundle must be built with a matching base href. Without this the built
# index.html keeps the default `<base href="/">` and every asset reference
# resolves to the site root, 404s, and the page renders blank.
flutterBuildFlags = ["--base-href=/web/"];
} }