Change8

fetch-router@0.19.0

Breaking Changes
📦 remixView on GitHub →
9 breaking3 features🔧 25 symbols

Summary

This release introduces major breaking changes by simplifying and restructuring the type definitions for route actions, controllers, request handlers, and middleware context handling. It also updates `context.get()` to return `undefined` when context values are missing.

⚠️ Breaking Changes

  • Route action, controller, request handler, and middleware helper types were simplified. `Action` now takes a route pattern/object as its first generic and request context as its optional second. `Controller` takes the route map first, context second. `RequestHandler` takes only the full request context. `Middleware` takes one context effect generic (context entry, tuple, or transform function). `BuildAction` is no longer exported.
  • The custom router matcher payload type was renamed from `MatchData` to `RouteEntry`. Update usages accordingly (e.g., `createMatcher<RouteEntry>()` instead of `createMatcher<MatchData>()`).
  • Manually annotated request handlers must now pass the full request context type as the only generic to `RequestHandler` (e.g., `RequestHandler<RequestContext<{ id: string }>>`).
  • Manually annotated middleware must now pass only the context transform type to `Middleware` (e.g., `Middleware<{ key: typeof Database; value: Database }>`).
  • Lower-level middleware context helper types (`MiddlewareContextTransform`, `ContextTransform`, `ApplyContextTransform`, `ApplyMiddleware`, and `ApplyMiddlewareTuple`) are no longer exported. Use `MiddlewareContext` instead.
  • `MiddlewareContext` now accepts middleware values, not middleware factory function types. Use `ReturnType<typeof factory>` when deriving context from a factory function.
  • Request context helper types were renamed to better describe the `RequestContext` they produce. Use `ContextWithParams`, `ContextWithEntries`, and `ContextWithEntry` for deriving contexts with params, multiple entries, or single entries, respectively.
  • Stored action objects and controllers no longer derive handler context from their local middleware tuple. Explicitly compose the full handler context and pass it to `Action`, `Controller`, `createAction()`, or `createController()` if local middleware adds required context.
  • `context.get(key)` now returns `undefined` if the value is missing and no default is provided. Code reading constructor keys (like `FormData` or `Session`) from a broad `RequestContext` must now handle the potential `undefined` return value (e.g., using optional chaining or explicit checks).

Migration Steps

  1. Update generic arguments for `Action`, `Controller`, `RequestHandler`, and `Middleware` based on the new type signatures.
  2. If you manually type actions or controllers, compose the full context type first and pass it as the second generic argument to `Action` or `Controller` if local middleware contributes context.
  3. Replace usages of `MatchData` with `RouteEntry` when using `createMatcher`.
  4. Update manual annotations for request handlers to use only the full request context type as the generic argument for `RequestHandler`.
  5. Update manual annotations for middleware to pass only the context transform type to `Middleware`.
  6. Replace usages of deprecated context helpers (`MiddlewareContextTransform`, `ContextTransform`, etc.) with `MiddlewareContext` or the newly named helpers (`ContextWithParams`, `ContextWithEntries`, `ContextWithEntry`).
  7. When using `MiddlewareContext`, pass `ReturnType<typeof factory>` if the middleware is created by a factory function.
  8. If reading constructor keys (like `FormData`) from a broad `RequestContext`, update code to safely handle `undefined` returns from `context.get(key)`.

✨ New Features

  • The recommended way to type stored handlers now involves augmenting `RouterTypes.context` once and using `createAction()`/`createController()` without `satisfies` clauses.
  • `MiddlewareContext` is the exported helper for deriving the request context produced by a middleware chain and accepts an optional base context as its second type parameter.
  • Middleware providing a single context value can now use a `{ key, value }` entry directly instead of wrapping it in a one-item tuple.

Affected Symbols