---
package: "@webjsdev/server"
version: 0.8.12
date: 2026-06-03T09:19:53.022Z
commit_count: 6
---
## Features

- **add a declarative webjs.redirects config for SEO redirects** ([#290](https://github.com/webjsdev/webjs/pull/290)) [`f2dcf03f`](https://github.com/webjsdev/webjs/commit/f2dcf03f)
  * feat: add a declarative webjs.redirects config for SEO redirects
  
  A package.json webjs.redirects array of { source, destination,
  permanent?, statusCode? } applies before routing: a URLPattern source
- **add a webjs.trailingSlash policy that canonicalizes with a 308** ([#291](https://github.com/webjsdev/webjs/pull/291)) [`c9d7d9af`](https://github.com/webjsdev/webjs/commit/c9d7d9af)
  * feat: add a webjs.trailingSlash policy that canonicalizes with a 308
  
  A page reachable at both /about and /about/ is duplicate content.
  webjs.trailingSlash ('never' strips, 'always' adds, 'ignore' default
- **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.
