denoland/fresh 2.2.0 → 2.3.0

Fresh 2.3.0 is a broad feature release with a lot of user-facing surface area. The biggest additions are first-class WebSocket support, View Transitions for client-side navigation, and a set of app/runtime options that make Fresh easier to run behind proxies and in more deployment setups.

What's new

  • Adds first-class WebSocket support through ctx.upgrade() and app.ws(). You can now upgrade a request in either bare mode, where you get { socket, response }, or managed mode with open, message, close, and error handlers. The new app.ws(path, handlers, options?) helper registers a GET route that upgrades automatically. (#3774)
  • Adds View Transitions API support for client-side navigation. It is opt-in with f-view-transition, works with links, popstate, and form submissions, and falls back cleanly when the browser does not support the API. (#3708)
  • Adds trustProxy to FreshConfig so ctx.url can respect X-Forwarded-Proto and X-Forwarded-Host headers behind reverse proxies. This is off by default. (#3757)
  • Adds an IP filter middleware with allow lists, deny lists, and CIDR subnet matching. Deny rules win over allow rules. (#3035)
  • Adds nonce support for inline <script> and <style> tags in CSP. Enable it with app.use(csp({ useNonce: true })), and Fresh will inject per-request nonces during SSR. (#3709)
  • Adds support for passing Temporal objects to islands. Serialization now covers all eight Temporal types, including Instant, PlainDate, ZonedDateTime, and Duration. (#3701)
  • Adds _freshIndicator support for partial form submits, so the loading signal now covers form submissions as well as anchor clicks. (#3753)
  • Adds support for multiple staticDir entries. Fresh now accepts string | string[] and searches directories in order, with the first match winning. (#3759)
  • Adds support for deno create @fresh/init for project initialization on Deno 2.7+, while keeping the older deno run -Ar jsr:@fresh/init flow available before 2.3.0. (#3706, #3746)
  • Adds HttpError for clients. (#3080)
  • Improves docs and the landing page substantially, including a full documentation audit and a refreshed homepage for Fresh 2.3. (#3712, #3775)

Breaking changes

  • FreshRequest.req is no longer readonly, so code that depended on that type modifier will need to account for the field being mutable now. (#2751)

Fixes

  • Fixes partial redirects so fresh-partial is preserved through ctx.redirect(), and falls back to a full navigation when a redirect target has no partials. (#3715, #3716)
  • Fixes active link detection to consider query parameters and leave an existing aria-current value alone. (#3755)
  • Fixes <Head> so it works client-side. (#3252)
  • Fixes trailing-slash mismatches that could make static routes 404. (#3721)
  • Fixes middleware matching for filesystem routes with optional parameters. (#3726)
  • Fixes programmatic layouts so they apply to index routes too. (#3725)
  • Fixes node_modules asset requests in dev mode, which unblocked fonts and other assets referenced from npm package CSS. (#3728)
  • Fixes the dev server when basePath is configured so Vite virtual URLs are passed through correctly. (#3730)
  • Fixes CSS Modules in _app, _layout, and _error, and across routes in dev. (#3764)
  • Fixes static file handling for spaces, commas, .well-known, and other encoded paths. (#3659, #3770, #3676)
  • Fixes the updater, update-tool output, and route error messages so they are more accurate and easier to act on. (#3630, #3754, #3718)
  • Fixes Vite asset caching so hashed JS and CSS assets are treated as immutable. (#3761)
  • Fixes WebSocket-related hydration and client-side behavior around invalid HTML nesting by warning instead of crashing. (#3762)

Other notable changes

  • Fresh now actually omits the client entry script when neither islands nor partials are used, matching the “no JS by default” promise. (#3696)
  • Middleware chains are pre-compiled at build time instead of being constructed per request. (#3104)
  • The Vite plugin got a broad set of compatibility fixes, including better Deno module resolution and improved CommonJS-to-ESM transforms for npm packages. (#3734, #3697)
  • deno create support was later rolled back in docs and init help for pre-2.3.0 flows, keeping the older init command as the default guidance until the new path is available. (#3746)
  • The docs site, homepage, and showcase were cleaned up and reorganized as part of the release. (#3712, #3703, #3775)

Contributors

@bartlomieju, @fry69, @marvinhagemeister, @Octo8080X, @Ionaru, @yukitaka, @ghalle, @CertainLach, @cuipeiyu, @dahlia, @Ott??

Only the most active 100 of 101 merged PRs were included. See the full compare view.