Remix Newsletter #37
This holiday season we're gifting stable APIs, a flag to opt in or out of React Transitions, the code to the Remix Store, and a sneak peek at our upcoming Remix Store drop.
Let's get to unwrapping 🎁 💿
React Router v7.9.6-v7.10.1
In the latest React Router release we've stabilized several previously experimental APIs, including split route modules, the Vite environment API, fetcher reset, and data strategy APIs. These releases also include bug fixes and improvements to error handling, navigation, and route matching.
New Features
Several experimental APIs have been promoted to stable in this release:
-
The
future.unstable_splitRouteModulesflag is now stable asfuture.v8_splitRouteModulesinreact-router.config.ts. This feature splits client-side route exports (clientLoader,clientAction,clientMiddleware,HydrateFallback) into separate chunks that can be loaded independently from the route component. -
The
future.unstable_viteEnvironmentApiflag is now stable asfuture.v8_viteEnvironmentApi. This enables support for the Vite Environment API, which provides a more flexible and powerful way to configure Vite environments. -
The
fetcher.unstable_reset()API is now stable asfetcher.reset(), giving you a clean way to reset fetchers back to their initialidlestate. -
The
DataStrategyMatch.shouldCallHandler()andDataStrategyMatch.shouldRevalidateArgsAPIs are now stable, replacing the deprecatedshouldLoadAPI for custom data strategies.
If you've been using any of these unstable APIs, you'll need to update your code. Check the upgrade guide for migration details.
Unstable Features
This release also includes several experimental APIs:
-
unstable_useTransitionsis a new flag that gives you control over React Router's usage ofReact.startTransitionandReact.useOptimistic. Read more about React Transitions below. -
Enhanced
unstable_onError: The client-sideunstable_onErrorcallback now receivesunstable_pattern,location, andparamsas parameters, enabling enhanced error reporting. This is a breaking change if you've already adoptedunstable_onError, as the signature has changed from(error, errorInfo?)to(error, { location, params, errorInfo? }).
Bug Fixes & Improvements
This release includes several important bug fixes and improvements:
- Fix Framework Mode bug where
defaultShouldRevalidateparameter would be incorrect afteractionreturned a 4xx/5xx response - Fix
fetcher.submitfailing with plain objects containing atagNameproperty - Fix promise returned from
useNavigatein Framework/Data Mode to properly track duration ofpopstatenavigations - Preserve
statusTextonErrorResponseinstance when throwingdata()from route handlers - Optimize
href()to avoid backtracking regex on splat routes - Fix internal type error in
useRoutetypes whenskipLibCheckis disabled - Fix ancestor thrown middleware errors before
next()on fetcher submissions - Fix issue with splat routes interfering with multiple calls to
patchRoutesOnNavigation - Normalize double-slashes in
resolvePath - Short circuit
HEADdocument requests before callingrenderToPipeableStreamto align with HTTP spec - Fix
useOptimisticstub for React 18 users to use a stable setter function, preventing potentialuseEffectloops when using<Link viewTransition> - Fix ESM import of
pkg-typespackage in@react-router/devto resolve issues on Node 20.18 - Update
valibotdependency to^1.2.0in@react-router/devto address security vulnerability
Check out the full React Router changelog ↗
React Transitions in React Router
React Router has been wrapping router state updates in React.startTransition since v7 to make the framework more Suspense-friendly. However, with React 19's new async Transitions and useOptimistic hook, we needed a way to better integrate with these features while also providing an opt-out for apps that don't wish to use Transitions.
The new unstable_useTransitions flag on router components (<HydratedRouter>, <RouterProvider>, or <BrowserRouter>) gives you control over this behavior:
-
Set to
false: Opts out ofstartTransitionentirely, which can help if you're usinguseSyncExternalStoreor other APIs that don't play well with Transitions. -
Set to
true(requires React 19 in Framework/Data Mode): Enables enhanced Transition behavior where<Link>and<Form>navigations are automatically wrapped inReact.startTransition, and router state updates during navigations are surfaced viaReact.useOptimistic. This means hooks likeuseNavigation()anduseFetchers()will show optimistic state during navigations, giving you instant feedback while data loads.
When enabled, only <Link> and <Form> are automatically Transition-enabled. For programmatic navigations with navigate() or submit(), you'll need to wrap them in startTransition yourself if you want Transition behavior.
We plan to make the opt-in behavior the default in React Router v8, but we'll retain the opt-out flag for edge cases. This gives you a smooth upgrade path and lets you experiment with React 19's concurrent features today.
Read the full React Transitions documentation ↗
Open Sourcing the Remix Store
We just open sourced the Remix Store. By making the store's source code public, we hope to benefit developers building with React Router as well as developers building Shopify stores.
We launched the store back in May with the intention of eventually open sourcing it. With something like a store though, where there is a real exchange of money for goods, there's plenty of room for abuse if done wrong. After 6 months of running the store and over 200 orders fulfilled, we've got everything sorted out to keep our store safe while also allowing anyone to run it locally and poke around/contribute.
We hope by open sourcing the Remix Store, developers will find it easier to contribute. Some of the code is good, some of it is mediocre, some of it is hacky, and some of it was just to get things over the finish line. Take a look at it, judge it, learn from it, improve it.
The store includes some fun features worth checking out, like a scroll-synced hero with a rotating 3D hoodie, an "exploding" collections header with parallax effects, optimistic cart updates, and glitchy 404/500 error pages. We're planning future improvements including new product drops, homepage updates, more affordable international shipping, and eventually rewriting the store in Remix 3.
Upcoming Remix Store Drop
We've got a new drop coming soon to the Remix Store 🟢
We have 4 limited edition products we plan to release as soon as they're available and just in time for the holidays!
Don't miss out on this drop, subscribe to receive Remix Store emails to hear about new products and be the first to know when they're available.
Subscribe to the Remix Store email list ↗
Connect at a Remix Meetup
Remix Meetups are run voluntarily by members of the community all around the globe with in-person and online options. These meetups feature local speakers, hackathons, workshops, and more!
No meetups near you? Reply to this email if you are interested in starting your own meetup. We've even created some guides to help you get started.
If you enjoy getting this email, please let us know! We'd love to hear from you, what you like about Remix and these updates, and any suggestions you have to improve them.
- The Remix Team