+++ title = "Add Trunk proxy config to Trunk.toml: forward /api/* to local API server" priority = 7 status = "todo" ticket_type = "task" dependencies = ["a9534d"] +++ The `quotesdb` project uses Trunk to build and serve the Yew (Wasm) frontend. During `trunk serve`, the UI runs on `localhost:8080` while the API runs separately on `localhost:3000`. Without a proxy, the browser would make cross-origin requests from `:8080` to `:3000`, requiring CORS headers. Triage a9534d resolved this: use Trunk's built-in `[[proxy]]` to forward `/api/*` requests to the API server. No CORS configuration is required anywhere — the proxy makes all API calls appear same-origin to the browser. **Chosen approach (triage a9534d):** Trunk proxy. Rationale: - Mirrors the production architecture: in production, Cloudflare routes `/api/*` to the Worker at the same domain as the Pages site. - Frontend uses relative URLs (`/api/quotes`, not `http://localhost:3000/api/quotes`) — the same URLs work in both dev and production without any configuration. - Zero CORS configuration needed in the API or the frontend. Tower-http CORS middleware is not required. - Standard, well-supported pattern for SPA development with a separate API backend. Add a `[[proxy]]` section to `Trunk.toml` in the `quotesdb/` root: ```toml [build] target = "index.html" [[proxy]] rewrite = "/api" backend = "http://localhost:3000" ``` This configuration means: - Requests from the browser to `http://localhost:8080/api/quotes` are forwarded to `http://localhost:3000/api/quotes`. - The `/api` prefix is preserved in the forwarded URL (Trunk appends the matched path to `backend`). - `trunk serve` handles the proxying automatically — no manual setup required by developers. - The API server port `3000` matches the plain Axum `cargo run` dev server (see ticket 6e829e). Local development workflow after this change: ```sh # Terminal 1 — start the API server cd quotesdb cargo run # Terminal 2 — start the UI dev server with proxy cd quotesdb trunk serve # Browser opens at http://localhost:8080 # API calls go to /api/* (proxied transparently to localhost:3000) ``` No environment variables, no hardcoded URLs, no CORS headers needed. In production (Cloudflare Pages + Workers), the same `/api/*` path prefix is used. Cloudflare can route `example.com/api/*` to the Worker and `example.com/*` to Pages via a Custom Domain or a Worker route rule. This is configured in infra/. The frontend code does not change. - API port must be `3000` — this must be consistent with however ticket 6e829e configures the local Axum server. - If the API port changes, update `Trunk.toml` accordingly and document the change. - Do not use `trunk.serve.proxy` (legacy format) — use `[[proxy]]` table array format. - This ticket's change is 3 lines in `Trunk.toml`. Keep it minimal. From the `quotesdb/` directory (requires `cargo run` running in another terminal): ```sh trunk serve & curl http://localhost:8080/api/quotes # should proxy to http://localhost:3000/api/quotes ``` At minimum, verify `trunk build` succeeds: ```sh trunk build ``` `chore(quotesdb): add Trunk proxy config to forward /api/* to local API server`