Skip to content

Networking (HTTPS, Proxy, CORS)

The dev server's networking layer lives in the server block: HTTPS, request proxying, CORS, a mount base, and the SPA history fallback. Host and port stay in devserver is everything else.

ts
import { defineConfig } from "vantris";

export default defineConfig({
  server: {
    https: true,
    proxy: { "/api": "http://localhost:8080" },
    cors: { origin: ["http://localhost:3000"], credentials: true },
    spaFallback: true,
    base: "/app/",
  },
});

Both runtimes go through the same createDevServer(), so all of this behaves identically under Node.js and Bun.

HTTPS

Serve the dev app over HTTPS. true generates a self-signed development certificate on the fly; pass your own with { cert, key }.

ts
server: { https: true }
ts
server: {
  https: {
    cert: "./certs/localhost.pem", // PEM contents or a file path
    key: "./certs/localhost-key.pem",
  },
}
  • With https: true, Vantris warns that it's a development certificate — browsers will prompt you to trust it. Use { cert, key } (e.g. from mkcert) for a trusted one.
  • cert/key accept either the PEM contents directly or a path resolved against root.

Proxy

Forward request-path prefixes to another origin — the usual fix for calling a backend on a different port without CORS during development.

ts
server: {
  proxy: {
    // shorthand: prefix → target
    "/api": "http://localhost:8080",

    // full form
    "/auth": {
      target: "https://auth.example.com",
      changeOrigin: true,                     // rewrite the Host header
      rewrite: (path) => path.replace(/^\/auth/, ""),
      secure: true,                           // verify TLS for https targets
    },
  },
}
  • target — the origin to forward to.
  • changeOrigin (default true) — rewrites the Host header to the target's, which many backends require.
  • rewrite — reshape the path before forwarding (e.g. strip the prefix).
  • secure (default true) — verify TLS certificates for an https target.
  • An unreachable target responds with a clear 502, so a misconfigured or down backend is obvious rather than a hang.

Proxying goes through the platform fetch, so it works the same on Node and Bun.

CORS

Off by default. true applies permissive defaults; an object customises the headers and answers preflight OPTIONS requests.

ts
server: { cors: true }
ts
server: {
  cors: {
    origin: ["http://localhost:3000"], // or true to reflect the request Origin
    methods: ["GET", "POST"],
    headers: ["Content-Type", "Authorization"],
    credentials: true,
  },
}
  • origin (default true) — allowed origin(s). true reflects the request's Origin.
  • methods — allowed methods (defaults cover the common verbs).
  • headers — echoed to Access-Control-Allow-Headers.
  • credentials (default false) — sets Access-Control-Allow-Credentials.

SPA fallback

History-API fallback for client-side routing — on by default. A route-like request (no file extension) falls back to index.html, so refreshing a client-side route works. A missing .js/.png still returns a real 404, so a genuinely missing asset isn't masked.

ts
server: { spaFallback: true } // default; set false to disable

The preview server applies the same fallback. See Preview.

Base path

Mount the dev server under a sub-path. Defaults to the top-level base; injected scripts and asset URLs respect it. Set it here to override just the dev server's mount point.

ts
export default defineConfig({
  base: "/app/",       // build + dev default
  server: {
    base: "/app/",     // dev-only override (usually unnecessary)
  },
});

Full example

ts
import { defineConfig } from "vantris";

export default defineConfig({
  dev: { port: 3000, host: "localhost" },
  server: {
    https: true,
    proxy: {
      "/api": "http://localhost:8080",
      "/ws": { target: "http://localhost:8080", changeOrigin: true },
    },
    cors: { origin: true, credentials: true },
    spaFallback: true,
  },
});

See the Server Options reference for the exact types of every field.

Released under the MIT License.