---
package: "@webjsdev/core"
version: 0.7.8
date: 2026-06-03T09:19:52.974Z
commit_count: 8
---
## 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)
  * feat: re-render page server actions with field errors and preserved input
  
  A page.{js,ts} may export action({ request, params, searchParams, url,
  formData }). A non-GET form posting to the page runs it: a success
- **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)
  * feat: mint a per-request CSP nonce and emit the Content-Security-Policy header
  
  webjs's CSP support was consume-only (ssr.js read a nonce from the
  inbound request header). Now, when webjs.csp is enabled, the handler
- **export a Metadata type for metadata and generateMetadata** ([#292](https://github.com/webjsdev/webjs/pull/292)) [`d63b2ae9`](https://github.com/webjsdev/webjs/commit/d63b2ae9)
  * feat: export a Metadata type for metadata and generateMetadata
  
  A page exports metadata / generateMetadata returning a metadata object,
  but webjs typed nothing, so a typo (titel, descripton, a wrong openGraph
- **generate typed route props and a route union for navigate()** ([#293](https://github.com/webjsdev/webjs/pull/293)) [`c18cc625`](https://github.com/webjsdev/webjs/commit/c18cc625)
  * feat: generate typed route props and a route union for navigate()
  
  A page/layout/route-handler default export receives { params, searchParams, url }, but webjs gave it no type, so searchParams was untyped everywhere and a [slug] route's params had to be hand-annotated with nothing tying the key to the folder name. Renaming [slug] to [id] silently broke every params.slug reference, and navigate('/blgo/123') type-checked fine only to 404 at runtime.
- **type the package.json webjs.* config block** ([#295](https://github.com/webjsdev/webjs/pull/295)) [`19dde265`](https://github.com/webjsdev/webjs/commit/19dde265)
  * feat: type the package.json webjs.* config block
  
  webjs reads a webjs.* object from package.json (elide, headers, redirects, csp, trailingSlash, and the body-limit / timeout knobs), but there was no type, schema, or validation, so a typo'd key was silently dropped and the feature it toggled stayed at default with no diagnostic. The config equivalent of an untyped API that fails open.
- **add JSON-LD structured data to the metadata API** ([#296](https://github.com/webjsdev/webjs/pull/296)) [`0554d1c2`](https://github.com/webjsdev/webjs/commit/0554d1c2)
  * feat: add JSON-LD structured data to the metadata API
  
  webjs had a near-complete metadata API but no way to emit JSON-LD, the highest-leverage modern SEO surface (Article, Product, BreadcrumbList, Organization, FAQ rich results) that Google reads only from <script type="application/ld+json">. Authors had to hand-inject a raw script via unsafeHTML, which is unergonomic and easy to get wrong.
- **support webjs.basePath for sub-path deployments** ([#298](https://github.com/webjsdev/webjs/pull/298)) [`aafee8f5`](https://github.com/webjsdev/webjs/commit/aafee8f5)
  * feat: support webjs.basePath for sub-path deployments
  
  An app deployed under a sub-path (example.com/app/) behind a proxy that does not strip the prefix was broken: every framework-emitted absolute URL (the importmap targets, modulepreload hints, the boot script's /__webjs/core/* specifiers and per-route module URLs, the dev reload src) assumed the app sat at the origin root, so they pointed at /__webjs/core/* instead of /app/__webjs/core/*, module resolution 404d, and the page never hydrated. createRequestHandler explicitly targets embedding, where a sub-path mount is the norm.

## Fixes

- **surface a missing webjs-frame instead of a silent full-page swap** ([#294](https://github.com/webjsdev/webjs/pull/294)) [`fdbfc999`](https://github.com/webjsdev/webjs/commit/fdbfc999)
  * fix: surface a missing webjs-frame instead of a silent full-page swap
  
  A frame-scoped navigation whose response omits the requested <webjs-frame id> silently blew away the whole page. In applySwap the frame branch was gated on (target && source); when the response lacked a matching frame (source null) or the target frame was gone (target null), control fell through to the layout-marker swap and then the full-body replaceChildren, wholesale-replacing the document with no warning and no event. An auth redirect returning a login page without the frame thus destroyed the page.
