---
package: "@webjsdev/server"
version: 0.8.10
date: 2026-06-03T01:13:24.874Z
commit_count: 7
---
## Features

- **re-render page server actions with field errors and preserved input** ([#277](https://github.com/webjsdev/webjs/pull/277)) [`bcd11a85`](https://github.com/webjsdev/webjs/commit/bcd11a85)

  A `page.{js,ts}` may export `action({ request, params, searchParams, url, formData })`. A non-GET form posting to the page runs it: a success result (or a thrown `redirect()`) responds 303 (Post/Redirect/Get), and a failure result re-renders the same page (422) with the result on `ctx.actionData` so the page repopulates field errors and the submitted values. Works with JS disabled (native form POST) and enhanced (the client router applies the 422 in place and follows the 303). The `ActionResult` envelope gains additive `fieldErrors` / `values` / `redirect`.

- **emit secure-by-default response headers with a per-path config** ([#278](https://github.com/webjsdev/webjs/pull/278)) [`dbd3e619`](https://github.com/webjsdev/webjs/commit/dbd3e619)

  Every served response now carries `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`, and `Permissions-Policy`, plus `Strict-Transport-Security` in production over HTTPS only (forwarded-proto aware). A `package.json` `webjs.headers` array (a URLPattern `source` plus key/value pairs) adds, overrides, or disables (`value: null`) a header per path. Precedence is secure defaults < path config < app middleware (a header the app already set is never clobbered).

- **mint a per-request CSP nonce and emit the Content-Security-Policy header** ([#279](https://github.com/webjsdev/webjs/pull/279)) [`79958c45`](https://github.com/webjsdev/webjs/commit/79958c45)

  CSP was consume-only (the SSR pipeline read a nonce from the inbound request header). When `webjs.csp` is enabled, the handler now mints a fresh CSPRNG nonce per request, stamps the same value on every inline script / importmap / modulepreload, and sets a matching `Content-Security-Policy` response header through the headers seam. Off by default; `true` enables a strict-dynamic + nonce policy, or an object customizes directives / report-only.

- **add a cors() middleware primitive for route handlers** ([#280](https://github.com/webjsdev/webjs/pull/280)) [`6527ac81`](https://github.com/webjsdev/webjs/commit/6527ac81)

  `cors({ origin, credentials, methods, allowedHeaders, exposedHeaders, maxAge })` is exported from `@webjsdev/server` as a webjs middleware usable in `middleware.js` or around a `route.js` handler. `origin` accepts a string, array (strings and RegExps), RegExp, predicate, or `'*'`. An OPTIONS preflight short-circuits a 204; an actual request reflects an allowed origin and appends `Vary: Origin`. `credentials` never emits a wildcard ACAO (and warns once on a wildcard origin). The shared resolver also backs the `expose()` path.

- **cap request body size (413) and set server timeouts** ([#281](https://github.com/webjsdev/webjs/pull/281)) [`7fe3b21e`](https://github.com/webjsdev/webjs/commit/7fe3b21e)

  Every request body read (RPC actions, exposed REST, `route.js` `readBody`, page-action forms, credentials sign-in) goes through one helper that fast-rejects an over-limit `Content-Length` and cancels a chunked stream the moment it crosses the cap, so an oversized body never buffers into memory; over the limit responds 413. Defaults 1 MiB JSON/RPC and 10 MiB multipart, configurable. The node:http server gets `requestTimeout` / `headersTimeout` / `keepAliveTimeout` to close the slowloris exposure.

- **fail fast on Node below 24 with a clear preflight** ([#282](https://github.com/webjsdev/webjs/pull/282)) [`a44583e1`](https://github.com/webjsdev/webjs/commit/a44583e1)

  `createRequestHandler` now throws a clear, actionable error at boot on a Node below 24 (webjs relies on Node 24's built-in TypeScript strip and recursive `fs.watch`). `dev.js` namespace-imports `node:module` so the package links on old Node and the message wins instead of a cryptic link-time `SyntaxError`. The minimum is read from the package's own `engines.node`.

- **validate env vars at boot via an optional env schema** ([#283](https://github.com/webjsdev/webjs/pull/283)) [`d958bec2`](https://github.com/webjsdev/webjs/commit/d958bec2)

  An optional app-root `env.{js,ts}` default-exports a schema object (`NAME` to a type or `{ type, required, optional, default, values, minLength, pattern }`; types string/number/boolean/url/enum) or a function `(env)` escape hatch. `createRequestHandler` runs it after the `.env` load, collects every error at once, coerces and applies defaults back into `process.env`, and fails fast with a message naming each offending var (never echoing the value). Absent `env.{js,ts}` is a no-op.
