Frontend Integration Guidelines¶
CLI tools and libraries have no browser-facing surface. Apply the points below to services that a single-page application (SPA) or other browser-based frontend calls directly.
Why CORS Is Structural, Not Optional¶
A SPA and its API almost always live on different origins (different port, subdomain, or domain) once deployed for real. Without CORS configured, browsers block every request from the frontend. This isn't a security feature to work around — it's the deployment topology the API has to support.
Configurable Allowed Origin¶
- Never default to
Access-Control-Allow-Origin: *. A wildcard turns any later oversight (e.g. a service that adds cookie-based auth) into a cross-origin data leak. - Never reflect the request's
Originheader back verbatim. That is functionally a wildcard, just harder to spot in review. - Read the allowed origin from an environment variable at startup (e.g.
CORS_ALLOWED_ORIGIN), falling back to a local-development default (http://localhost:3000). Configuration belongs in the environment, never baked into the image (seeci_cd.md).
The Preflight Trap (C++)¶
cpp-httplib dispatches routes by exact path and method. A per-route Options handler is easy to
forget on the next endpoint, and a route registered only with Get never sees the browser's
preflight request at all. Use set_pre_routing_handler instead (see the generated
src/app/cors.hpp/cors.cpp): it runs before path/method routing, so one registration answers
preflight for every current and future path — no per-route opt-in needed. Go's and Java's HTTP
stacks don't have this trap: their middleware/filter chains already wrap every request before
route matching.
Directives¶
- Never set
Access-Control-Allow-Originto*or to the reflected requestOrigin; use a fixed, configured origin - Read the allowed origin from an environment variable with a local-development default; never hardcode it
- In cpp-httplib, answer
OPTIONSpreflight in the pre-routing handler, not a per-route handler; it runs before routing and covers every path