fix(deps): update dependency react-router-dom to v7 #87
No reviewers
Labels
No labels
area/ai
area/backend
area/frontend
area/infra
area/scheduler
area/wled
good-first-issue
priority/high
priority/low
priority/medium
type/bug
type/chore
type/ci-cd
type/docs
type/feature
type/qa
v1.0.0
v1.1.0
v1.2.0
v2.0.0
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/Iris-WLED!87
Loading…
Reference in a new issue
No description provided.
Delete branch "renovate/major-react-router-monorepo"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR contains the following updates:
^6.26.2→^7.0.0Release Notes
remix-run/react-router (react-router-dom)
v7.18.3Compare Source
v7.18.2Compare Source
v7.18.1Compare Source
v7.18.0Compare Source
Date: 2026-06-16
What's Changed
CSRF Check Logic Fix
We made a bug fix in our underlying CSRF checks in this release that may be a "breaking bug fix" for some users deployed behind a reverse proxy. The CSRF check now checks directly against the
hostin therequesturl provided, instead of looking directly at HTTP headers which is an adapter concern. If your adapter is not setting the expected host in the request URL, you may need to add the new internal host to yourallowedActionOriginsconfig. This is most likely to occur in@react-router/serveapps or@react-router/expressapps without thetrust proxysetting enabled. We recommend testing this against application mutation requests as part of your upgrade.Minor Changes
@react-router/architect- Add auseRequestContextDomainNameoption tocreateRequestHandlerto derive request URL hosts from the API Gateway request context (#15185)Patch Changes
react-router- Fix server handler prerender responses when usingssr: falseandfuture.v8_trailingSlashAwareDataRequests: true(#15173)react-router- Use theServerRouternoncefor nonce-aware SSR components when they don't provide their own value so strict CSP pages can load them (#15170)react-router- Useturbo-streamto serialize and deserialize Framework Mode hydration errors (#15175)react-router- Optimize route matching by extending precomputed route branches to include matchers (#15186)react-router- Use the constructedrequestURLhostinstead of header checks when validating action request origins in the CSRF check (#15185)react-router- Remove the un-documented custom error serialization logic from Data Mode SSR built-in hydration flows (#15175)react-router- Validate protocols in RSC render redirects (#15177)react-router- Consolidate url normalization logic and better handle mixed slashes (#15176)@react-router/dev- Pass Viteserver.watchconfig to child compiler in development mode. (#15178)@react-router/dev- Ignore external Vite server environments in Framework Mode build hooks (#14883)future.v8_viteEnvironmentApiis enabled, React Router previously treated any non-client Vite environment as its own server build@react-router/express- Adjust express adapter host computation (#15185)x-forwarded-hostbased ontrust proxysettingFull Changelog:
v7.17.0...v7.18.0v7.17.0Compare Source
Date: 2026-06-04
Minor Changes
react-router- Ship a subset of the official documentation inside thereact-routerpackage (#15121)node_modules/react-router/docs, letting AI coding agents and the React Router agent skills read official docs locallyapi/),community/content, and tutorials (tutorials/)Patch Changes
@react-router/dev- Fix future flag warning URLs and only log each future flag warning one time (#15138)Unstable Changes
⚠️ Unstable features are not recommended for production use
@react-router/dev- Prevent RSC route module server exports from being scanned by the client dependency optimizer whenfuture.unstable_optimizeDepsis enabled. (#15005)Full Changelog:
v7.16.0...v7.17.0v7.16.0Compare Source
Date: 2026-05-28
Minor Changes
react-router- Stabilizefuture.unstable_trailingSlashAwareDataRequestsasfuture.v8_trailingSlashAwareDataRequests(#15098)@react-router/dev- Stabilizefuture.unstable_trailingSlashAwareDataRequestsasfuture.v8_trailingSlashAwareDataRequests(#15098)@react-router/dev- Log future flag warnings for upcoming React Router v8 flags (#15029)v8_middleware,v8_splitRouteModules,v8_viteEnvironmentApi,v8_passThroughRequests,v8_trailingSlashAwareDataRequestsPatch Changes
react-router- Disable manifest path when lazy route dicovery is disabled (#15068)react-router- Fix browser URL creation to use the configured history window instead of the global window. (#15066)createBrowserURLImplso custom window contexts keep the correct URL origin.react-router- FixuseNavigation()return type to preserve discriminated union across navigation states (#15095)react-router- WidenMetaDescriptorscript:ld+jsontype fromLdJsonObjecttoLdJsonObject | LdJsonObject[]to permit multiple JSON-LD schemas in a single<script type="application/ld+json">tag emitted by<Meta />(#15082)react-router-dom- Remove stale/invalidunpkgfield frompackage.json. This was removed from other packages with the release of v7 but missed in thereact-router-domre-export package (#15075)@react-router/express- Ignore writes after Express responses close (#15107)@react-router/node- Honor Node writable backpressure inwriteReadableStreamToWritableandwriteAsyncIterableToWritable(#15071)'drain'whenwritable.write()returnsfalseinstead of letting chunks accumulate in the writable's internal buffer.@react-router/serve- NormalizeassetsBuildDirectorypath separators inreact-router-serveso Windows-built server artifacts can serve/assets/*correctly when run on Linux. (#14982)Full Changelog:
v7.15.1...v7.16.0v7.15.1Compare Source
Date: 2026-05-14
What's New
useRouterState(unstable)Following our Less is More design goal, this release includes a new
unstable_useRouterState()hook (Framework + Data Mode) that consolidates access to active and pending router states (RFC, Roadmap Issue).This should allow you to consolidate usages of a bunch of different hooks which will likely be marked deprecated later on in v8 and potentially removed in an eventual v9:
Patch Changes
react-router- MemoizeuseFetchersto return a stable identity and only change if fetchers changed (#15028)react-router- Update router to operate on fetcher Maps in an immutable manner to avoid delayed React renders from potentially reading an updated but not yet committed Map. This could result in brief flickers in some fetcher-driven optimistic UI scenarios (#15028)react-router- FixserverLoader()returning stale SSR data when a client navigation aborts pending hydration before the hydrationclientLoaderresolves (#15022)react-router- FixRouterProvideronErrorcallback not being called for synchronous initial loader errors in SPA mode (#15039) (#14942)react-router- Internal refactor to consolidate mutation request detection through shared utility (#15033)@react-router/dev- Fixbasenameconflicting withappdirectory name when Vitebaseis set (#15027)baseconfig and React Routerbasenameboth match the app directory name (e.g.base: "/app/",basename: "/app/"), Vite would strip the base prefix from server-build virtual module import paths, causing "Failed to load url /root.tsx" errors/@​fs/absolute paths for those imports to bypass Vite's base-stripping logicUnstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Add a newunstable_useRouterState()hook that consolidates access to active and pending router states (RFC: #12358) (#15017)Full Changelog:
v7.15.0...v7.15.1v7.15.0Compare Source
Date: 2026-05-05
What's Changed
Stabilizations
We've stabilized a bunch of APIs in this release in preparation for a React Router v8 release hopefully in the next month or two. These flag/prop renames are breaking changes if you've already opted into the unstable APIs so please make sure you make the appropriate changes if so.
future.unstable_passThroughRequests→future.v8_passThroughRequestsfuture.unstable_subResourceIntegrity→ top-levelconfig.subResourceIntegrityprerender.unstable_concurrency→prerender.concurrencyunstable_url→url(loader, action, middleware, instrumentation args)unstable_instrumentations→instrumentationsServerInstrumentation,ClientInstrumentation, etc.)unstable_pattern→pattern(loader, action, middleware, instrumentation args)unstable_defaultShouldRevalidate→defaultShouldRevalidateunstable_useTransitions→useTransitionsunstable_mask→mask(on<Link>,useLinkClickHandler,useNavigate, andLocation)Route matching optimizations
We've added a handful of route matching optimizations in this release for Framework and Data mode. The changes are mostly related to caching the internal flattened/ranked route branches and reducing additional calls to
matchRoutesalong the critical path. This should result in improved performance during both server-side request handling and client-side navigations.Minor Changes
react-router- Stabilizeunstable_defaultShouldRevalidateasdefaultShouldRevalidateon<Link>,<Form>,useLinkClickHandler,useSubmit,fetcher.submit, andsetSearchParams(14999)react-router- Stabilize the instrumentation APIs (14999)unstable_instrumentationsis nowinstrumentationsunstable_patternis nowpatternunstable_ServerInstrumentation,unstable_ClientInstrumentation,unstable_InstrumentRequestHandlerFunction,unstable_InstrumentRouterFunction,unstable_InstrumentRouteFunction, andunstable_InstrumentationHandlerResulttypes have had theirunstable_prefixes removedreact-router- Stabilizeunstable_maskasmaskon<Link>,useLinkClickHandler, anduseNavigate, and rename the correspondingLocation.unstable_maskfield toLocation.mask(14999)react-router- Stabilize theunstable_normalizePathoption onstaticHandler.queryandstaticHandler.queryRouteasnormalizePath(14999)react-router- Stabilizefuture.unstable_passThroughRequestsasfuture.v8_passThroughRequests(14999)react-router- Removeunstable_subResourceIntegrityfrom the runtimeFutureConfigtype; the flag is now controlled by the top-levelsubResourceIntegrityoption inreact-router.config.ts(14999)react-router- Stabilizeunstable_urlasurlonloader,action, andmiddlewarefunction args (14999)react-router- Stabilizeunstable_useTransitionsasuseTransitionson<BrowserRouter>,<HashRouter>,<HistoryRouter>,<MemoryRouter>,<Router>,<RouterProvider>,<HydratedRouter>, anduseLinkClickHandler(14999)@react-router/dev- Stabilizefuture.unstable_passThroughRequestsasfuture.v8_passThroughRequests(14999)@react-router/dev- Stabilizeprerender.unstable_concurrencyasprerender.concurrency(14999)@react-router/dev- Stabilizefuture.unstable_subResourceIntegrityas a top-levelsubResourceIntegrityconfig option inreact-router.config.ts(14999)Patch Changes
react-router- Addnonceto<Scripts><link rel="modulepreload">elements (if provided) (af5d49b)react-router- Fix a bug withunstable_defaultShouldRevalidate={false}where parent routes that did not export ashouldRevalidatefunction could be incorrectly included in the single fetch call for new child route data (#15012)react-router- Markmaskas an optional field inLocationfor easier mocking in unit tests (#14999)react-router- Improve server-side route matching performance by pre-computing flattened/cached route branches (#14967)react-router- Cache flattened/ranked route branches to optimize server-side route matching (#14967)react-router- Improve route matching performance in Framework/Data Mode (#14971)matchRoutesin data router scenarios7.6.0(#13562)matchesbut always updatingmatch.routeto the latest route in themanifestFull Changelog:
v7.14.2...v7.15.0v7.14.2Compare Source
Date: 2026-04-21
Patch Changes
react-router- Remove the un-documented custom error serialization logic from the internal turbo-stream implementation. React Router only automatically handles serialization ofErrorand it's standard subtypes (SyntaxError,TypeError, etc.). (#14992)react-router- Properly handle parent middleware redirects duringfetcher.load(#14974)react-router- Remove redundantOmit<RouterProviderProps, "flushSync">fromreact-router/domRouterProvider(#14874)react-router- Improved types forgeneratePath'sparamarg (#14984)Type errors when required params are omitted:
Allow omission of optional params:
Allows extra keys:
@react-router/dev- Fix typegen for layouts without pages (#14875)pages: ;in.react-router/types/+routes.tswhen a route corresponded to 0 pagespages: never;is correctly generated for those casesUnstable Changes
⚠️ Unstable features are not recommended for production use
@react-router/dev- Forunstable_reactRouterRSCVite plugin consumers, require@vitejs/plugin-reactin user Vite config, and more reliably split route modules (#14965)unstable_reactRouterRSCVite plugin - please install@vitejs/plugin-reactand add thereactplugin to your Vite plugins array.Full Changelog:
v7.14.1...v7.14.2v7.14.1Compare Source
Date: 2026-04-13
Patch Changes
react-router- Fix a potential race condition that can occur when rendering aHydrateFallbackand initial loaders land before therouter.subscribecall happens in theRouterProviderlayout effect (#14497)react-router- Normalize double-slashes in redirect paths (#14962)@react-router/dev- Add TypeScript 6 support to peer dependency ranges (#14935)Full Changelog:
v7.14.0...v7.14.1v7.14.0Compare Source
Date: 2026-04-02
Minor Changes
Patch Changes
react-router- Remove recursion from vendoredturbo-streamv2 implementation allowing for encoding/decoding of large payloads (#14838)react-router- FixencodeViaTurboStreammemory leak via unremovedAbortSignallistener (#14900)@react-router/dev- Support for prerendering multiple server bundles withv8_viteEnvironmentApi(#14921)Unstable Changes
⚠️ Unstable features are not recommended for production use
@react-router/dev- Pre-rendering and SPA Mode support for RSC Framework Mode (#14907)@react-router/dev- Updatereact-router revealto support RSC Framework Mode forentry.client,entry.rsc,entry.ssr(#14904)react-router- Support<Link prefetch>in RSC Framework Mode (#14902)react-router- Add support for new route module exports in unstable RSC Framework Mode (#14901)⚠️ This is a breaking change if you have already adopted RSC Framework Mode in it's unstable state - you will need to update your route modules to export the new annotations
The following route module components have their own mutually exclusive server component counterparts:
defaultServerComponentErrorBoundaryServerErrorBoundaryLayoutServerLayoutHydrateFallbackServerHydrateFallbackIf you were previously exporting a
ServerComponent, yourErrorBoundary,Layout, andHydrateFallbackwere also implicitly server componentsIf you want to keep those as server components - rename them and prefix them with
ServerIf you were previously importing the implementations of those components from a client module, you can inline them
Full Changelog:
v7.13.2...v7.14.0v7.13.2Compare Source
Date: 2026-03-23
What's Changed
Pass-through Requests (unstable)
By default, React Router normalizes the
request.urlpassed to yourloader,action, andmiddlewarefunctions by removing React Router's internal implementation details (.datasuffixes,index+_routesquery params). This release introduces a newfuture.unstable_passThroughRequestsflag to disable this normalization and pass the raw HTTPrequestinstance to your handlers.In addition to reducing server-side overhead by eliminating multiple
new Request()calls on the critical path, this also provides additional visibility to your route handlers/instrumentations allowing you to differentiate document from data requests.If you were previously relying on the normalization of
request.url, you can switch to use the new siblingunstable_urlparameter which contains aURLinstance representing the normalized location:Route handlers/middleware
unstable_urlparameterWe have added a new
unstable_url: URLparameter to route handler methods (loader,action,middleware, etc.) that contains the normalized URL the application is navigating to or fetching with React Router implementation details removed (.datasuffix,index/_routesquery params).This parameter is primarily needed when adopting the new
future.unstable_passthroughRequestsfuture flag as a way to continue accessing the normalized URL. If you don't have the flag enabled, thenunstable_urlwill matchrequest.url.Patch Changes
react-router- FixclientLoader.hydratewhen an ancestor route is also hydrating aclientLoader(#14835)react-router- Fix type error when passing Framework Mode route components usingRoute.ComponentPropstocreateRoutesStub(#14892)react-router- Fix percent encoding in relative path navigation (#14786)react-router- Internal refactor to consolidate framework-agnostic/React-specific route type layers - no public API changes (#14765)@react-router/dev- Fixreact-router devcrash when Unix socket files exist in the project root (#14854)@react-router/dev- Escape redirect locations in pre-rendered redirect HTML (#14880)create-react-router- replacechalkwithpicocolors(#14837)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Sync protocol validation to RSC flows (#14882)react-router- Addfuture.unstable_passThroughRequestsflag (#14775)react-router- Add a newunstable_url: URLparameter to route handler methods (loader,action,middleware, etc.) representing the normalized URL the application is navigating to or fetching, with React Router implementation details removed (.datasuffix,index/_routesquery params) (#14775)Full Changelog:
v7.13.1...v7.13.2v7.13.1Compare Source
Date: 2026-02-23
What's Changed
URL Masking (unstable)
This release includes a new
<Link unstable_mask>API which brings first-class support for URL masking to Framework/Data Mode (RFC). This allows the same type of UI you could achieve in Declarative Mode via manualbackgroundLocationmanagement. That example has been converted to Data Mode using the new API here.Patch Changes
react-router- Clear timeout whenturbo-streamencoding completes (#14810)react-router- Improve error message whenOriginheader is invalid (#14743)react-router- FixmatchPathoptional params matching without a"/"separator. (#14689)matchPath("/users/:id?", "/usersblah")now returns nullmatchPath("/test_route/:part?", "/test_route_more")now returns null.react-router- FixHydrateFallbackrendering during initial lazy route discovery with matching splat route (#14740)react-router- Preserve query parameters and hash on manifest version mismatch reload (#14813)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- RSC: fix null reference exception in bad codepath leading to invalid route tree comparisons (#14780)react-router- RSC: addunstable_getRequestAPI (#14758)react-router- RSC: Update failed origin checks to return a 400 status and appropriate UI instead of a generic 500 (#14755)react-router- Add support for<Link unstable_mask>in Framework/Data Mode which allows users to navigate to a URL in the router but "mask" the URL displayed in the browser (#14716)This is useful for contextual routing usages such as displaying an image in a modal on top of a gallery, but displaying a browser URL directly to the image that can be shared and loaded without the contextual gallery in the background
The masked location, if present, will be available on
useLocation().unstable_maskso you can detect whether you are currently masked or notMasked URLs only work for SPA use cases, and will be removed from
history.stateduring SSRThis provides a first-class API to mask URLs in Framework/Data Mode to achieve the same behavior you could do in Declarative Mode via manual
backgroundLocationmanagement.Full Changelog:
v7.13.0...v7.13.1v7.13.0Compare Source
Date: 2026-01-23
Minor Changes
react-router- AddcrossOriginprop toLinkscomponent (#14687)Patch Changes
react-router- Fix double slash normalization foruseNavigatepaths with a colon (#14718)react-router- Fix missingnonceon inlinecriticalCss(#14691)react-router- Update failed origin checks to return a 400 status instead of a 500 (#14737)react-router- LoosenallowedActionOriginsglob check so**matches all domains (#14722)@react-router/dev- Bump@remix-run/node-fetch-serverdep (#14704)@react-router/fs-routes- Fix route file paths when routes directory is outside of the app directory (#13937)Full Changelog:
v7.12.0...v7.13.0v7.12.0Compare Source
Date: 2026-01-07
Security Notice
This release addresses 3 security vulnerabilities:
Minor Changes
react-router- Add additional layer of CSRF protection by rejecting submissions to UI routes from external origins (#14708)allowedActionOriginsconfig field inreact-router.config.tswhere you can specify external originsPatch Changes
react-router- FixgeneratePathwhen used with suffixed params (i.e.,/books/:id.json) (#14269)react-router- Escape HTML in scroll restoration keys (#14705)react-router- Validate redirect locations (#14706)@react-router/dev- FixMaximum call stack size exceedederrors when HMR is triggered against code with cyclic imports (#14522)@react-router/dev- Skip SSR middleware invite previewserver for SPA mode (#14673)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- PreserveclientLoader.hydrate=truewhen using<HydratedRouter unstable_instrumentations>(#14674)react-router- Pass<Scripts nonce>value through to the underlyingimportmapscripttag when usingfuture.unstable_subResourceIntegrity(#14675)react-router- ExportUNSAFE_createMemoryHistoryandUNSAFE_createHashHistoryalongsideUNSAFE_createBrowserHistoryfor consistency (#14663)unstable_HistoryRoutermigrate from v6->v7 so they can adopt the newer APIs@react-router/dev- Add a newfuture.unstable_trailingSlashAwareDataRequestsflag to provide consistent behavior ofrequest.pathnameinsidemiddleware,loader, andactionfunctions on document and data requests when a trailing slash is present in the browser URL. (#14644)Currently, your HTTP and
requestpathnames would be as follows for/a/b/cand/a/b/c//a/b/crequestpathname`/a/b/c/a/b/c✅/a/b/c.data/a/b/c✅/a/b/c/requestpathname`/a/b/c//a/b/c/✅/a/b/c.data/a/b/c⚠️With this flag enabled, these pathnames will be made consistent though a new
_.dataformat for client-side.datarequests:/a/b/crequestpathname`/a/b/c/a/b/c✅/a/b/c.data/a/b/c✅/a/b/c/requestpathname`/a/b/c//a/b/c/✅/a/b/c/_.data⬅️/a/b/c/✅This a bug fix but we are putting it behind an opt-in flag because it has the potential to be a "breaking bug fix" if you are relying on the URL format for any other application or caching logic
Enabling this flag also changes the format of client side
.datarequests from/_root.datato/_.datawhen navigating to/to align with the new format - This does not impact therequestpathname which is still/in all casesFull Changelog:
v7.11.0...v7.12.0v7.11.0Compare Source
Date: 2025-12-17
What's Changed
We've added
vite previewsupport and stabilized the client-sideonErrorAPI - please make the appropriate changes if you've adopted theunstable_onErrorAPI already in a prior release.vite previewSupportWe've added support for
vite previewwhen using Framework mode to make it easy to preview your production build.Stabilized Client-side
onErrorThe existing
<RouterProvider unstable_onError>/<HydratedRouter unstable_onError>APIs have been stabilized as<RouterProvider onError>/<HydratedRouter onError>. Please see the Error Reporting docs for more information.Call-site Revalidation Opt-out (unstable)
We've added initial unstable support for call-site revalidation opt-out via a new
unstable_defaultShouldRevalidateflag (RFC). This flag is available on all navigation/fetcher submission APIs to alter standard revalidation behavior. If any routes include ashouldRevalidatefunction, then the flag value will be passed to that function so the route has the final say on revalidation behavior.This flag is also available on non-submission navigational use cases - for example, you may want to opt-out of revalidation when adding a search param that doesn't impact the UI:
Minor Changes
react-router- Stabilize<HydratedRouter onError>/<RouterProvider onError>(#14546)@react-router/dev- Addvite previewsupport (#14507)Patch Changes
react-router- Fixunstable_useTransitionsprop on<Router>component to permit omission for backwards compatibility (#14646)react-router- Allow redirects to be returned from client side middleware (#14598)react-router- HandledataStrategyimplementations that return insufficient result sets by adding errors for routes without any available result (#14627)@react-router/serve- Updatecompressionandmorgandependencies to addresson-headersCVE: GHSA-76c9-3jph-rj3q (#14652)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- RSC: Support for throwingdata()and Response from server component render phase (#14632)data()insteadreact-router- RSC: Support for throwingredirectResponse's at render time (#14596)react-router- RSC:routeRSCServerRequestreplacefetchServerwithserverResponse(#14597)@react-router/dev- RSC (Framework mode): Manual chunking forreactandreact-routerdeps (#14655)@react-router/dev- RSC (Framework mode): Optimizereact-server-dom-webpackif in projectpackage.json(#14656)@react-router/{dev,serve}- RSC (Framework mode): Support custom entrypoints (#14643)react-router- Add a newunstable_defaultShouldRevalidateflag to various APIs to allow opt-ing out of standard revalidation behaviors (#14542)Full Changelog:
v7.10.1...v7.11.0v7.10.1Compare Source
Date: 2025-12-04
Patch Changes
react-router- Update theuseOptimisticstub we provide for React 18 users to use a stable setter function to avoid potentialuseEffectloops - specifically when using<Link viewTransition>(#14628)@react-router/dev- Import ESM packagepkg-typeswith a dynamicimport()to fix issues on Node 20.18 (#14624)@react-router/dev- Updatevalibotdependency to^1.2.0to address GHSA-vqpr-j7v3-hqw9 (#14608)Full Changelog:
v7.10.0...v7.10.1v7.10.0Compare Source
Date: 2025-12-02
What's Changed
We've stabilized a handful of existing APIs and future flags in this release, please make the appropriate changes if you'd adopted any of these APIs in their unstable state!
Stabilized
future.v8_splitRouteModulesThe existing
future.unstable_splitRouteModulesflag has been stabilized asfuture.v8_splitRouteModulesinreact-router.config.ts. Please see the docs for more information on adopting this flag.Stabilized
future.v8_viteEnvironmentApiThe existing
future.unstable_viteEnvironmentApiflag has been stabilized asfuture.v8_viteEnvironmentApiinreact-router.config.ts. Please see the docs for more information on adopting this flag.Stabilized
fetcher.reset()The existing
fetcher.unstable_reset()API has been stabilized asfetcher.reset().Stabilized
DataStrategyMatch.shouldCallHandler()The existing low-level
DataStrategyMatch.unstable_shouldCallHandler()/DataStrategyMatch.unstable_shouldRevalidateArgsAPIs have been stabilized asDataStrategyMatch.shouldCallHandler()/DataStrategyMatch.shouldRevalidateArgs. Please see the docs for information about using a customdataStrategyand how to migrate away from the deprecatedDataStrategyMatch.shouldLoadAPI if you are using that today.Minor Changes
react-router- Stabilizefetcher.reset()(#14545)fetcher.unstable_reset()- please update your code to usefetcher.reset()react-router- Stabilize thedataStrategymatch.shouldCallHandler()/match.shouldRevalidateArgsAPIs (#14592)match.shouldLoadAPI is now marked deprecated in favor of these more powerful alternativesmatch.unstable_shouldCallHandler()/match.unstable_shouldRevalidateArgs- please update your code to usematch.shouldCallHandler()/match.shouldRevalidateArgs@react-router/dev- Stabilizefuture.v8_splitRouteModules, replacingfuture.unstable_splitRouteModules(#14595)future.unstable_splitRouteModules- please update yourreact-router.config.ts@react-router/dev- Stabilizefuture.v8_viteEnvironmentApi, replacingfuture.unstable_viteEnvironmentApi(#14595)future.unstable_viteEnvironmentApi- please update yourreact-router.config.tsPatch Changes
react-router- Fix a Framework Mode bug where thedefaultShouldRevalidateparameter toshouldRevalidatewould not be correct afteractionreturned a 4xx/5xx response (truewhen it should have beenfalse) (#14592)shouldRevalidatefunction relied on that parameter, you may have seen unintended revalidationsreact-router- Fixfetcher.submitfailing with plain objects containing atagNameproperty (#14534)react-router- Fix the promise returned fromuseNavigatein Framework/Data Mode so that it properly tracks the duration ofpopstatenavigations (i.e.,navigate(-1)) (#14524)react-router- PreservestatusTexton theErrorResponseinstance when throwingdata()from a route handler (#14555)react-router- Optimizehref()to avoid backtracking regex on splat (#14329)@react-router/dev- Fix internal type error inuseRoutetypes that surfaces whenskipLibCheckis disabled (#14577)@react-router/dev- Load environment variables before evaluatingroutes.ts(#14446)For example, you can now compute your routes based on
VITE_-prefixed environment variablesUnstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Addunstable_patternto the parameters for client sideunstable_onError(#14573)react-router- Refactor howunstable_onErroris called internally byRouterProviderto avoid potential strict mode issues (#14573)react-router- Add newunstable_useTransitionsflag to routers to give users control over the usage ofReact.startTransitionandReact.useOptimistic(#14524)<HydratedRouter unstable_transition>/<RouterProvider unstable_transition>React.startTransitionReact.startTransitiontrueif you run into this scenario to get the enhanceduseOptimisticbehavior (requires React 19)trueReact.startTransition(as they are without the flag)Link/Formnavigations will be wrapped inReact.startTransitionuseNavigate/useSubmitif you wish to opt out of this outerReact.startTransitioncall for the navigationReact.useOptimistic(i.e.,useNavigation(),useFetchers(), etc.)falseReact.startTransitionorReact.useOptimisticon any navigations or state changes<BrowserRouter unstable_useTransitions>React.startTransitiontrueReact.startTransition(as they are without the flag)Link/Formnavigations will be wrapped inReact.startTransitionfalseReact.startTransitionon any navigations or state changesFull Changelog:
v7.9.6...v7.10.0v7.9.6Compare Source
Date: 2025-11-13
Security Notice
This release addresses 1 security vulnerability:
Patch Changes
react-router- Properly handle ancestor thrown middleware errors beforenext()on fetcher submissions (#14517)react-router- Fix issue with splat routes interfering with multiple calls topatchRoutesOnNavigation(#14487)react-router- Normalize double-slashes inresolvePath(#14529)@react-router/dev- Use a dynamicimport()to load ESM-onlyp-mapdependency to avoid issues on Node 20.18 and below (#14492)@react-router/dev- Short circuitHEADdocument requests before callingrenderToPipeableStreamin the defaultentry.server.tsxto more closely align with the spec (#14488)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Addlocation/paramsas arguments to client-sideunstable_onErrorto permit enhanced error reporting (#14509)⚠️ This is a breaking change if you've already adopted
unstable_onErrorThe second parameter has changed to an object including
errorInfo,location, andparams:Full Changelog:
v7.9.5...v7.9.6v7.9.5Compare Source
Date: 2025-10-29
What's Changed
Instrumentation (unstable)
This release adds new
unstable_instrumentationAPIs that will allow you to add runtime instrumentation logic to various aspects of your application (server handler, client navigations/fetches, loaders, actions, middleware,route.lazy). For more information, please see the docs.Patch Changes
react-router- Ensure action handlers run for routes with middleware even if no loader is present (#14443)@react-router/dev- Ensure route navigation doesn't remove CSSlinkelements used by dynamic imports (#14463)@react-router/dev- Typegen: only register route module types for routes within the app directory (#14439)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Moveunstable_RSCHydratedRouterand utils toreact-router/domexport (#14457)react-router- Add a type-safehandlefield tounstable_useRoute()(#14462)For example:
react-router- Addunstable_instrumentationsAPI to allow users to add observability to their apps by instrumenting route loaders, actions, middlewares, lazy, as well as server-side request handlers and client side navigations/fetches (#14412)entry.server.tsx:export const unstable_instrumentations = [...]entry.client.tsx:<HydratedRouter unstable_instrumentations={[...]} />createBrowserRouter(routes, { unstable_instrumentations: [...] })react-router- Add a newunstable_patternparameter to loaders/actions/middleware which contains the un-interpolated route pattern (i.e.,/blog/:slug) which is useful for aggregating logs/metrics by route in instrumentation code (#14412)@react-router/dev- Introduce aprerender.unstable_concurrencyoption, to support running the pre-rendering concurrently, potentially speeding up the build (#14380)Full Changelog:
v7.9.4...v7.9.5v7.9.4Compare Source
Date: 2025-10-08
Security Notice
This release addresses 1 security vulnerability:
createFileSessionStorage()with unsigned cookiesWhat's Changed
useRoute()(unstable)This release includes a new
unstable_useRoute()hook that provides a type-safe way to access routeloaderData/actionDatafrom a specific route in Framework Mode. Think if it like a better version ofuseRouteLoaderDatathat works with the typegen system and also supportsactionData. Check out the changelog entry below for more information.Patch Changes
@react-router/dev- Updatevalibotdependency to^1.1.0(#14379)@react-router/node- Validate format of incoming session ids increateFileSessionStorage(#14426)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- handle external redirects in from server actions (#14400)react-router- New (unstable)useRoutehook for accessing data from specific routes (#14407)For example, let's say you have an
adminroute somewhere in your app and you want any child routes ofadminto all have access to theloaderDataandactionDatafromadmin.You might even want to create a reusable widget that all of the routes nested under
admincould use:In framework mode,
useRouteknows all your app's routes and gives you TS errors when invalid route IDs are passed in:useRoutereturnsundefinedif the route is not part of the current page:Note: the
rootroute is the exception since it is guaranteed to be part of the current page.As a result,
useRoutenever returnsundefinedforroot.loaderDataandactionDataare marked as optional since they could be accessed before theactionis triggered or after theloaderthrew an error:If instead of a specific route, you wanted access to the current route's
loaderDataandactionData, you can calluseRoutewithout arguments:This usage is equivalent to calling
useLoaderDataanduseActionData, but consolidates all route data access into one hook:useRoute.Note: when calling
useRoute()(without a route ID), TS has no way to know which route is the current route.As a result,
loaderDataandactionDataare typed asunknown.If you want more type-safety, you can either narrow the type yourself with something like
zodor you can refactor your app to pass down typed props to yourAdminWidget:Full Changelog:
v7.9.3...v7.9.4v7.9.3Compare Source
Date: 2025-09-26
Patch Changes
react-router- Fix Data Mode regression causing a 404 during initial load in whenmiddlewareexists without anyloaderfunctions (#14393)react-router- Do not try to useturbo-streamto decode CDN errors that never reached the server (#14385)ErrorBoundaryinstead of a generic "Unable to decode turbo-stream response" errorFull Changelog:
v7.9.2...v7.9.3v7.9.2Compare Source
Date: 2025-09-24
What's Changed
This release contains a handful of bug fixes, but we think you'll be most excited about the new unstable stuff 😉.
RSC Framework Mode (unstable)
This release includes our first release of unstable support for RSC in Framework Mode! You can read more about it in our blog post and the docs.
Fetcher Reset (unstable)
This release also includes a new (long-requested)
fetcher.unstable_reset()API to reset fetchers back to their initialidlestate.Patch Changes
react-router- Ensure client-side router runs clientmiddlewareduring initialization data load (if required) even if no loaders exist (#14348)react-router- Fixmiddlewareprop not being supported on<Route>when used with a data router viacreateRoutesFromElements(#14357)react-router- UpdatecreateRoutesStubto work withmiddleware(#14348)<RoutesStub future={{ v8_middleware: true }} />flag to enable the propercontexttypereact-router- Update Lazy Route Discovery manifest requests to use a singular comma-separatedpathsquery param instead of repeatedpquery params (#14321)react-router- Fail gracefully on manifest version mismatch logic ifsessionStorageaccess is blocked (#14335)react-router- UpdateuseOutletreturned element to have a stable identity in-between route changes (#13382)react-router- Handle encoded question mark and hash characters in ancestor splat routes (#14249)@react-router/dev- Switch internal vite plugin Response logic to use@remix-run/node-fetch-server(#13927)@react-router/dev- Fixpresetsfutureflags being ignored during config resolution (#14369)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Addfetcher.unstable_reset()API (#14206)react-router- In RSC Data Mode, handle SSR'd client errors and re-try in the browser (#14342)react-router- Enable full transition support for the RSC router (#14362)@react-router/dev- Add unstable support for RSC Framework Mode (#14336)@react-router/serve- Disablecompression()middleware in RSC framework mode (#14381)Full Changelog:
v7.9.1...v7.9.2v7.9.1Compare Source
Date: 2025-09-12
Patch Changes
Futureinterface naming frommiddleware->v8_middleware(#14327)Full Changelog:
v7.9.0...v7.9.1v7.9.0Compare Source
Date: 2025-09-12
Security Notice
This release addresses 1 security vulnerability:
What's Changed
Stable Middleware and Context APIs
We have removed the
unstable_prefix from the following APIs and they are now considered stable and ready for production use:RouterContextProvidercreateContextcreateBrowserRoutergetContextoption<HydratedRouter>getContextpropPlease see the Middleware Docs, the Middleware RFC, and the Client-side Context RFC for more information.
Minor Changes
Patch Changes
react-router- Updatehref()to correctly process routes that have an extension after the parameter or are a single optional parameter (#13797)react-router- Escape HTML inmeta()JSON-LD content (#14316)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- RSC: Add react-serverAwaitcomponent implementation (#14261)react-router- RSC: Fix hydration errors for routes that only have client loaders when using RSC in Data Mode along with a custom basename (#14264)react-router- RSC: Makehreffunction available in areact-servercontext (#14262)react-router- RSC: Decode each timegetPayload()is called to allow for "in-context" decoding and hoisting of contextual assets (#14248)Full Changelog:
v7.8.2...v7.9.0v7.8.2Compare Source
Date: 2025-08-22
Patch Changes
react-router- MaintainReadonlyMapandReadonlySettypes in server response data. (#13092)react-router- Fixbasenameusage without a leading slash in data routers (#11671)react-router- FixTypeErrorif you throw frompatchRoutesOnNavigationwhen no partial matches exist (#14198)react-router- Properly escape interpolated param values ingeneratePath()(#13530)@react-router/dev- Fix potential memory leak in defaultentry.server(#14200)Unstable Changes
⚠️ Unstable features are not recommended for production use
Client-side
onErrorreact-router- Add<RouterProvider unstable_onError>/<HydratedRouter unstable_onError>prop for client side error reporting (#14162)Middleware
react-router- Delay serialization of.dataredirects to 202 responses until after middleware chain (#14205)react-router- Update client middleware so it returns thedataStrategyresults up the chain allowing for more advanced post-processing middleware (#14151, #14212)react-router- Remove Data Modefuture.unstable_middlewareflag fromcreateBrowserRouter(#14213)getLoadContexttype behavior changeRSC
react-router- Allow opting out of revalidation on server actions with hidden$SKIP_REVALIDATIONinput (#14154)Full Changelog:
v7.8.1...v7.8.2v7.8.1Compare Source
Date: 2025-08-15
Patch Changes
react-router- Fix usage of optional path segments in nested routes defined using absolute paths (#14135)react-router- Fix optional static segment matching inmatchPath(#11813)react-router- Fix pre-rendering when abasenameis set withssr:false(#13791)react-router- Properly convert returned/throwndata()values toResponseinstances viaResponse.json()in resource routes and middleware (#14159, #14181)@react-router/dev- Update generatedRoute.MetaArgstype soloaderDatais only potentially undefined when anErrorBoundaryexport is present (#14173)Unstable Changes
⚠️ Unstable features are not recommended for production use
Middleware
react-router- Bubble client pre-nextmiddleware errors to the shallowest ancestor that needs to load, not strictly the shallowest ancestor with a loader (#14150)react-router- Propagate non-redirectResponsevalues thrown from middleware to the error boundary on document/data requests (#14182)RSC
react-router- ProvideisRouteErrorResponseutility inreact-serverenvironments (#14166)react-router- HandlemetaandlinksRoute Exports in RSC Data Mode (#14136)Full Changelog:
v7.8.0...v7.8.1v7.8.0Compare Source
Date: 2025-08-07
What's Changed
Consistently named
loaderDatavaluesEver noticed the discrepancies in loader data values handed to you by the framework? Like, we call it
loaderDatain your component props, but thenmatch.datain your matches? Yeah, us too - as well as some keen-eyed React Router users who raised this in a proposal. We've added newloaderDatafields alongside existingdatafields in a few lingering spots to align with theloaderDatanaming used in the newRoute.*APIs.Improvements/fixes to the middleware APIs (unstable)
The biggest set of changes in
7.8.0are to theunstable_middlewareAPI's as we move closer to stabilizing them. If you've adopted the middleware APIs for early testing, please read the middleware changes below carefully. We hope to stabilize these soon so please let us know of any feedback you have on the API's in their current state!Minor Changes
react-router- Addnonceprop toLinks&PrefetchPageLinks(#14048)react-router- AddloaderDataarguments/properties alongside existingdataarguments/properties to provide consistency and clarity betweenloaderDataandactionDataacross the board (#14047)Route.MetaArgs,Route.MetaMatch,MetaArgs,MetaMatch,Route.ComponentProps.matches,UIMatch@deprecatedwarnings have been added to the existingdataproperties to point users to newloaderDataproperties, in preparation for removing thedataproperties in a future major releasePatch Changes
react-router- Prevent "Did not find corresponding fetcher result" console error when navigating during afetcher.submitrevalidation (#14114)react-router- Switch Lazy Route Discovery manifest URL generation to use a standaloneURLSearchParamsinstance instead ofURL.searchParamsto avoid a major performance bottleneck in Chrome (#14084)react-router- Adjust internal RSC usage ofReact.useto avoid Webpack compilation errors when using React 18 (#14113)react-router- Remove dependency on@types/nodein TypeScript declaration files (#14059)react-router- Fix types forUIMatchto reflect that theloaderData/dataproperties may beundefined(#12206)When an
ErrorBoundaryis being rendered, not all active matches will have loader data available, since it may have been theirloaderthat threw to trigger the boundaryThe
UIMatch.datatype was not correctly handing this and would always reflect the presence of data, leading to the unexpected runtime errors when anErrorBoundarywas rendered⚠️ This may cause some type errors to show up in your code for unguarded
match.dataaccesses - you should properly guard forundefinedvalues in those scenarios.@react-router/dev- Fix rename without mkdir in Vite plugin (#14105)Unstable Changes
⚠️ Unstable features are not recommended for production use
RSC
react-router- Fix Data Mode issue where routes that returnfalsefromshouldRevalidatewould be replaced by an<Outlet />(#14071)react-router- Proxy server action side-effect redirects from actions for document andcallServerrequests (#14131)Middleware
react-router- Change theunstable_getContextsignature onRouterProvider,HydratedRouter, andunstable_RSCHydratedRouterso that it returns anunstable_RouterContextProviderinstance instead of aMapused to construct the instance internally (#14097)unstable_getContextpropreact-router- Run client middleware on client navigations even if no loaders exist (#14106)react-router- Convert internal middleware implementations to use the newunstable_generateMiddlewareResponseAPI (#14103)react-router- Ensure resource route errors go throughhandleErrorw/middleware enabled (#14078)react-router- Propagate returnedResponsefrom server middleware ifnextwasn't called (#14093)react-router- Allow server middlewares to returndata()values which will be converted into aResponse(#14093, #14128)react-router- Update middleware error handling so that thenextfunction never throws and instead handles any middleware errors at the properErrorBoundaryand returns theResponseup through the ancestornextfunction (#14118)nextcalls intry/catchyou should be able to remove thosereact-router- Bubble client-side middleware errors prior tonextto the appropriate ancestor error boundary (#14138)react-router- When middleware is enabled, make thecontextparameter read-only (Readonly<unstable_RouterContextProvider>) so that TypeScript will not allow you to write arbitrary fields to it in loaders, actions, or middleware. (#14097)react-router- Rename and alter the signature/functionality of theunstable_respondAPI instaticHandler.query/staticHandler.queryRoute(#14103)This only impacts users using
createStaticHandler()for manual data loading during non-Framework Mode SSRThe API has been renamed to
unstable_generateMiddlewareResponsefor clarityThe main functional change is that instead of running the loaders/actions before calling
unstable_respondand handing you the result, we now pass aquery/queryRoutefunction as a parameter and you execute the loaders/actions inside your callback, giving you full access to pre-processing and error handlingThe
queryversion of the API now has a signature of(query: (r: Request) => Promise<StaticHandlerContext | Response>) => Promise<Response>The
queryRouteversion of the API now has a signature of(queryRoute: (r: Request) => Promise<Response>) => Promise<Response>This allows for more advanced usages such as running logic before/after calling
queryand direct error handling of errors thrown from query⚠️ This is a breaking change if you've adopted the
staticHandlerunstable_respondAPI@react-router/{architect,cloudflare,express,node}- Change thegetLoadContextsignature (type GetLoadContextFunction) whenfuture.unstable_middlewareis enabled so that it returns anunstable_RouterContextProviderinstance instead of aMapused to construct the instance internally (#14097)type unstable_InitialContextexportgetLoadContextdocs for more informationgetLoadContextfunctionChanges by Package
create-react-routerreact-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v7.7.1...v7.8.0v7.7.1Compare Source
Date: 2025-07-24
Patch Changes
@react-router/dev- Update to Prettier v3 for formatting when runningreact-router reveal --no-typescript(#14049)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- RSC Data Mode: fix bug where routes with errors weren't forced to revalidate whenshouldRevalidatereturnedfalse(#14026)react-router- RSC Data Mode: fixMatched leaf route at location "/..." does not have an element or Componentwarnings when error boundaries are rendered (#14021)Full Changelog:
v7.7.0...v7.7.1v7.7.0Compare Source
Date: 2025-07-16
What's Changed
Unstable RSC APIs
We're excited to introduce experimental support for RSC in Data Mode via the following new APIs:
unstable_RSCHydratedRouterunstable_RSCStaticRouterunstable_createCallServerunstable_getRSCStreamunstable_matchRSCServerRequestunstable_routeRSCServerRequestFor more information, check out the blog post and the RSC Docs.
Minor Changes
create-react-router- Add Deno as a supported and detectable package manager. Note that this detection will only work with Deno versions 2.0.5 and above. If you are using an older version version of Deno then you must specify the --package-manager CLI flag set todeno. (#12327)@react-router/remix-config-routes-adapter- ExportDefineRouteFunctiontype alongsideDefineRoutesFunction(#13945)Patch Changes
react-router- HandleInvalidCharacterErrorwhen validating cookie signature (#13847)react-router- Pass a copy ofsearchParamsto thesetSearchParamscallback function to avoid mutations of the internalsearchParamsinstance (#12784)searchParamswhen a navigation is blocked because the internal instance gets out of sync withuseLocation().searchreact-router- Support invalidDateinturbo-streamv2 fork (#13684)react-router- In Framework Mode, clear critical CSS in development after initial render (#13872, #13995)react-router- Strip search parameters frompatchRoutesOnNavigationpathparam for fetcher calls (#13911)react-router- Skip scroll restoration onuseRevalidator()calls because they're not new locations (#13671)react-router- Support unencoded UTF-8 routes in prerender config withssrset tofalse(#13699)react-router- Do not throw if the url hash is not a valid URI component (#13247)react-router- RemoveContent-Lengthheader from Single Fetch responses (#13902)react-router- Fix a regression increateRoutesStubintroduced with the middleware feature (#13946)As part of that work we altered the signature to align with the new middleware APIs without making it backwards compatible with the prior
AppLoadContextAPIThis permitted
createRoutesStubto work if you were opting into middleware and the updatedcontexttypings, but brokecreateRoutesStubfor users not yet opting into middlewareWe've reverted this change and re-implemented it in such a way that both sets of users can leverage it
⚠️ This may be a breaking bug for if you have adopted the unstable Middleware feature and are using
createRoutesStubwith the updated API.@react-router/dev- Updatevite-nodeto^3.2.2to support Vite 7 (#13781)@react-router/dev- Properly handlehttpsprotocol in dev mode (#13746)@react-router/dev- Fix missing styles when Vite'sbuild.cssCodeSplitoption is disabled (#13943)@react-router/dev- Allow.mtsand.mjsextensions for route config file (#13931)@react-router/dev- Fix prerender file locations whencwddiffers from project root (#13824)@react-router/dev- Improve chunk error logging when a chunk cannot be found during the build (#13799)@react-router/dev- Fix incorrectly configuredexternalConditionswhich had enabledmodulecondition for externals and broke builds with certain packages (like Emotion) (#13871)Unstable Changes
⚠️ Unstable features are not recommended for production use
Changes by Package
create-react-routerreact-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v7.6.3...v7.7.0v7.6.3Compare Source
Date: 2025-06-27
Patch Changes
react-router- Do not serialize types foruseRouteLoaderData<typeof clientLoader>(#13752)For types to distinguish a
clientLoaderfrom aserverLoader, you MUST annotateclientLoaderargs:@react-router/cloudflare- RemovetsupfrompeerDependencies(#13757)@react-router/dev- Add Vite 7 support (#13748)@react-router/dev- Skippackage.jsonresolution checks when a customentry.server.(j|t)sxfile is provided (#13744)@react-router/dev- Add validation for a route's id not being 'root' (#13792)@react-router/fs-routes@react-router/remix-config-routes-adapter- UsereplaceAllfor normalizing windows file system slashes (#13738)@react-router/node- Remove old "install" package exports (#13762)Full Changelog:
v7.6.2...v7.6.3v7.6.2Compare Source
Date: 2025-06-03
Patch Changes
create-react-router- Updatetar-fs(#13675)react-router- (INTERNAL) Slight refactor of internalheaders()function processing for use with RSC (#13639)react-router@react-router/dev- Avoid additionalwith-propschunk in Framework Mode by moving route module component prop logic from the Vite plugin toreact-router(#13650)@react-router/dev- Whenfuture.unstable_viteEnvironmentApiis enabled and an absolute Vitebasehas been configured, ensure critical CSS is handled correctly during development (#13598)@react-router/dev- Updatevite-node(#13673)@react-router/dev- Fix typegen for non-{.js,.jsx,.ts,.tsx} routes like .mdx (#12453)@react-router/dev- Fix href types for optional dynamic params (#13725)7.6.1 introduced fixes for
hrefwhen using optional static segments,but those fixes caused regressions with how optional dynamic params worked in 7.6.0:
Now, optional static segments are expanded into different paths for
href, but optional dynamic params are not.This way
hrefcan unambiguously refer to an exact URL path, all while keeping the number of path options to a minimum.Additionally, you can pass
paramsfrom component props without needing to narrow them manually:Full Changelog:
v7.6.1...v7.6.2v7.6.1Compare Source
Date: 2025-05-25
Patch Changes
react-router- Partially revert optimization added in7.1.4to reduce calls tomatchRoutesbecause it surfaced other issues (#13562)react-router- UpdateRoute.MetaArgsto reflect thatdatacan be potentiallyundefined(#13563)loaderthrew an error to it's ownErrorBoundary, but it also arises in the case of a 404 which renders the rootErrorBoundary/metabut the rootloaderdid not run because not routes matchedreact-router- Avoid initial fetcher execution 404 error when Lazy Route Discovery is interrupted by a navigation (#13564)react-router- Properlyhrefreplaces splats*(#13593)href("/products/*", { "*": "/1/edit" }); // -> /products/1/edit@react-router/architect- Update@architect/functionsfrom^5.2.0to^7.0.0(#13556)@react-router/dev- Prevent typegen with route files that are outside theapp/directory (#12996)@react-router/dev- Add additional logging tobuildcommand output when cleaning assets from server build (#13547)@react-router/dev- Don't clean assets from server build whenbuild.ssrEmitAssetshas been enabled in Vite config (#13547)@react-router/dev- Fix typegen when same route is used at multiple paths (#13574)For example,
routes/route.tsxis used at 4 different paths here:Previously, typegen would arbitrarily pick one of these paths to be the "winner" and generate types for the route module based on that path
Now, typegen creates unions as necessary for alternate paths for the same route file
@react-router/dev- Better types forparams(#13543)For example:
Previously,
paramsforroutes/routewere calculated as{ p: string, r: string }.This incorrectly ignores params that could come from child routes
If visiting
/parent/1/route/2/child1/3/4, the actual params passed toroutes/routewill have a type of{ p: string, r: string, c1a: string, c1b: string }Now,
paramsare aware of child routes and autocompletion will include child params as optionals:You can also narrow the types for
paramsas it is implemented as a normalized union of params for each page that includesroutes/route:@react-router/dev- Fixhreffor optional segments (#13595)Type generation now expands paths with optionals into their corresponding non-optional paths
For example, the path
/user/:id?gets expanded into/userand/user/:idto more closely model visitable URLshrefthen uses these expanded (non-optional) paths to construct type-safe paths for your app:This becomes even more important for static optional paths where there wasn't a good way to indicate whether the optional should be included in the resulting path:
Unstable Changes
⚠️ Unstable features are not recommended for production use
@react-router/dev- Renamed internalreact-router/route-moduleexport toreact-router/internal(#13543)@react-router/dev- RemovedInfoexport from generated+types/*files (#13543)@react-router/dev- Normalize dirent entry path across node versions when generating SRI manifest (#13591)Full Changelog:
v7.6.0...v7.6.1v7.6.0Compare Source
Date: 2025-05-08
What's Changed
routeDiscoveryConfig OptionWe've added a new config option in
7.6.0which grants you more control over the Lazy Route Discovery feature. You can now configure the/__manifestpath if you're running multiple RR applications on the same server, or you can also disable the feature entirely if your application is small enough and the feature isn't necessary.Automatic Types for Future Flags
Some future flags alter the way types should work in React Router. Previously, you had to remember to manually opt-in to the new types. For example, for
future.unstable_middleware:It was up to you to keep the runtime future flags synced with the types for those flags. This was confusing and error-prone.
Now, React Router will automatically enable types for future flags. That means you only need to specify the runtime future flag:
Behind the scenes, React Router will generate the corresponding
declare moduleinto.react-router/types. Currently this is done in.react-router/types/+register.tsbut this is an implementation detail that may change in the future.Minor Changes
react-router- Added a newrouteDiscoveryoption inreact-router.config.tsto configure Lazy Route Discovery behavior (#13451)react-router- Add support for route component props increateRoutesStub(#13528)This allows you to unit test your route components using the props instead of the hooks:
@react-router/dev- Automatic types for future flags (#13506)Patch Changes
You may notice this list is a bit larger than usual! The team ate their vegetables last week and spent the week squashing bugs to work on lowering the issue count that had ballooned a bit since the v7 release.
react-router- Fixreact-routermodule augmentation forNodeNext(#13498)react-router- Don't bundlereact-routerinreact-router/domCJS export (#13497)react-router- Fix bug where a submittingfetcherwould get stuck in aloadingstate if a revalidatingloaderredirected (#12873)react-router- Fix hydration error if a serverloaderreturnedundefined(#13496)react-router- Fix initial load 404 scenarios in data mode (#13500)react-router- StabilizeuseRevalidator'srevalidatefunction (#13542)react-router- Preserve status code if aclientActionthrows adata()result in framework mode (#13522)react-router- Be defensive against leading double slashes in paths to avoidInvalid URLerrors from the URL constructor (#13510)new URL("//", window.location.origin)react-router- RemoveNavigatordeclaration fornavigator.connection.saveDatato avoid messing with any other types beyondsaveDatain user land (#13512)react-router- FixhandleErrorparamsvalues on.datarequests for routes with a dynamic param as the last URL segment (#13481)react-router- Don't trigger anErrorBoundaryUI before the reload when we detect a manifest version mismatch in Lazy Route Discovery (#13480)react-router- Inlineturbo-stream@2.4.1dependency and fix decoding ordering ofMap/Setinstances (#13518)react-router- Only render dev warnings during dev (#13461)react-router- Short circuit post-processing on aborteddataStrategyrequests (#13521)Cannot read properties of undefined (reading 'result')@react-router/dev- Support project root directories without apackage.jsonif it exists in a parent directory (#13472)@react-router/dev- When providing a custom Vite config path via the CLI--config/-cflag, default the project root directory to the directory containing the Vite config when not explicitly provided (#13472)@react-router/dev- In aroutes.tscontext, ensure the--modeflag is respected forimport.meta.env.MODE(#13485)import.meta.env.MODEwithin aroutes.tscontext was always"development"for thedevandtypegen --watchcommands, but otherwise resolved to"production". These defaults are still in place, but if a--modeflag is provided, this will now take precedence.@react-router/dev- Ensure consistent project root directory resolution logic in CLI commands (#13472)@react-router/dev- When executingreact-router.config.tsandroutes.tswithvite-node, ensure that PostCSS config files are ignored (#13489)@react-router/dev- When extracting critical CSS during development, ensure it's loaded from the client environment to avoid issues with plugins that handle the SSR environment differently (#13503)@react-router/dev- Fix "Status message is not supported by HTTP/2" error during dev when using HTTPS (#13460)@react-router/dev- Update config whenreact-router.config.tsis created or deleted during development (#12319)@react-router/dev- Skip unnecessaryroutes.tsevaluation before Vite build is started (#13513)@react-router/dev- FixTS2300: Duplicate identifiererrors caused by generated types (#13499)href(.react-router/types/+register.ts), causing type checking errorsUnstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Fix a few bugs with error bubbling in middleware use-cases (#13538)@react-router/dev- Whenfuture.unstable_viteEnvironmentApiis enabled, ensure thatbuild.assetsDirin Vite config is respected whenenvironments.client.build.assetsDiris not configured (#13491)Changes by Package
create-react-routerreact-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v7.5.3...v7.6.0v7.5.3Compare Source
Date: 2025-04-28
Patch Changes
react-router- Fix bug where bubbled action errors would result inloaderDatabeing cleared at the handlingErrorBoundaryroute (#13476)react-router- Handle redirects fromclientLoader.hydrateinitial load executions (#13477)Full Changelog:
v7.5.2...v7.5.3v7.5.2Compare Source
Date: 2025-04-24
Security Notice
Fixed 2 security vulnerabilities that could result in cache-poisoning attacks by sending specific headers intended for build-time usage for SPA Mode and Pre-rendering (GHSA-f46r-rw29-r322, GHSA-cpj6-fhp6-mr6j).
Patch Changes
react-router- Adjust approach for Pre-rendering/SPA Mode via headers (#13453)react-router- Update Single Fetch to also handle the 204 redirects used in?_datarequests in Remix v2 (#13364).datarequests from outside the scope of React Router (i.e., anexpress/honomiddleware) the same way they did in Remix v2 before Single Fetch was implemented.datarequest wih a response as follows:X-Remix-Redirect: <new-location>headerX-Remix-Replace: trueorX-Remix-Reload-Document: trueheaders to replicatereplace()/redirectDocument()functionalityFull Changelog:
v7.5.1...v7.5.2v7.5.1Compare Source
Date: 2025-04-17
Patch Changes
react-router- When using the object-basedroute.lazyAPI, theHydrateFallbackandhydrateFallbackElementproperties are now skipped when lazy loading routes after hydration (#13376)If you move the code for these properties into a separate file, since the hydrate properties were unused already (if the route wasn't present during hydration), you can avoid downloading them at all. For example:
react-router- Fix single fetch bug where no revalidation request would be made when navigating upwards to a reused parent route (#13253)react-router- Properly revalidate pre-rendered paths when param values change when usingssr:false+prerenderconfigs (#13380)react-router- Fix pre-rendering when a loader returns a redirect (#13365)react-router- Do not automatically addnulltostaticHandler.query()context.loaderDataif routes do not have loaders (#13223)undefinedfrom loaders, our prior check ofloaderData[routeId] !== undefinedwas no longer sufficient and was changed to arouteId in loaderDatacheck - thesenullvalues can cause issues for this new checkcreateStaticHandler()/<StaticRouterProvider>, and usingcontext.loaderDatato control<RouterProvider>hydration behavior on the clientUnstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Add better error messaging whengetLoadContextis not updated to return aMap(#13242)react-router- Update context type forLoaderFunctionArgs/ActionFunctionArgswhen middleware is enabled (#13381)react-router- Add a newunstable_runClientMiddlewareargument todataStrategyto enable middleware execution in customdataStrategyimplementations (#13395)react-router- Add support for the newunstable_shouldCallHandler/unstable_shouldRevalidateArgsAPIs indataStrategy(#13253)Full Changelog:
v7.5.0...v7.5.1v7.5.0Compare Source
Date: 2025-04-04
What's Changed
route.lazyObject APIWe've introduced a new
route.lazyAPI which gives you more granular control over the lazy loading of route properties that you could not achieve with theroute.lazy()function signature. This is useful for Framework mode and performance-critical library mode applications.⚠️ This is a breaking change if you have adopted the
route.unstable_lazyMiddlewareAPI which has been removed in favor ofroute.lazy.unstable_middleware. See theUnstable Changessection below for more information.Minor Changes
react-router- Add granular object-based API forroute.lazyto support lazy loading of individual route properties (#13294)Patch Changes
@react-router/dev- Update optionalwranglerpeer dependency range to supportwranglerv4 (#13258)@react-router/dev- Reinstate dependency optimization in the child compiler to fixdepsOptimizer is required in dev modeerrors when usingvite-plugin-cloudflareand importing Node.js builtins (#13317)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Introducefuture.unstable_subResourceIntegrityflag that enables generation of animportmapwithintegrityfor the scripts that will be loaded by the browser (#13163)react-router- Remove support for theroute.unstable_lazyMiddlewareproperty (#13294)route.lazy.unstable_middlewareAPI@react-router/dev- Whenfuture.unstable_viteEnvironmentApiis enabled, ensure critical CSS in development works when using a custom Vitebasehas been configured (#13305)Changes by Package
create-react-routerreact-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v7.4.1...v7.5.0v7.4.1Compare Source
Date: 2025-03-28
Security Notice
Fixed a security vulnerability that allowed URL manipulation and potential cache pollution via the
HostandX-Forwarded-Hostheaders due to inadequate port sanitization (GHSA-4q56-crqp-v477/CVE-2025-31137).Patch Changes
react-router- Dedupe calls toroute.lazyfunctions (#13260)@react-router/dev- Fix path in prerender error messages (#13257)@react-router/dev- Fix typegen for virtual modules whenmoduleDetectionis set toforce(#13267)@react-router/express- Better validation ofx-forwarded-hostheader to prevent potential security issues (#13309)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Fix types onunstable_MiddlewareFunctionto avoid type errors when a middleware doesn't return a value (#13311)react-router- Add support forroute.unstable_lazyMiddlewarefunction to allow lazy loading of middleware logic (#13210)unstable_middlewarefromroute.lazyroute.unstable_middlewareproperty is no longer supported in the return value fromroute.lazyroute.unstable_lazyMiddleware@react-router/dev- When bothfuture.unstable_middlewareandfuture.unstable_splitRouteModulesare enabled, splitunstable_clientMiddlewareroute exports into separate chunks when possible (#13210)@react-router/dev- Improve performance offuture.unstable_middlewareby ensuring that route modules are only blocking during the middleware phase when theunstable_clientMiddlewarehas been defined (#13210)Full Changelog:
v7.4.0...v7.4.1v7.4.0Compare Source
Date: 2025-03-19
Minor Changes
@react-router/dev- Generate types forvirtual:react-router/server-buildmodule (#13152)Patch Changes
react-router- Fix root loader data on initial load redirects in SPA mode (#13222)react-router- Load ancestor pathless/index routes in lazy route discovery for upwards non-eager-discovery routing (#13203)react-router- FixshouldRevalidatebehavior forclientLoader-only routes inssr:trueapps (#13221)@react-router/dev- Fix conflicts with other Vite plugins that use theconfigureServerand/orconfigurePreviewServerhooks (#13184)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- If a middleware throws an error, ensure we only bubble the error itself vianext()and are no longer leaking theMiddlewareErrorimplementation detail (#13180)catch-ing errors thrown by thenext()function in your middlewaresreact-router- FixRequestHandlerloadContextparameter type when middleware is enabled (#13204)react-router- UpdateRoute.unstable_MiddlewareFunctionto have a return value ofResponse | undefinedinstead ofResponse | void(#13199)@react-router/dev- Whenfuture.unstable_splitRouteModulesis set to"enforce", allow both splittable and unsplittable root route exports since it's always in a single chunk (#13238)@react-router/dev- Whenfuture.unstable_viteEnvironmentApiis enabled, allow plugins that override the default SSR environment (such as@cloudflare/vite-plugin) to be placed before or after the React Router plugin (#13183)Changes by Package
create-react-routerreact-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v7.3.0...v7.4.0v7.3.0Compare Source
Date: 2025-03-06
Minor Changes
fetcherKeyas a parameter topatchRoutesOnNavigation(#13061)Patch Changes
react-router- Detect and handle manifest-skew issues on new deploys during active sessions (#13061)fetchercalls to undiscovered routes, this mismatch will trigger a document reload of the current pathreact-router- Skip resource route flow in dev server in SPA mode (#13113)react-router- Fix single fetch_root.datarequests when abasenameis used (#12898)react-router- Fix types forloaderDataandactionDatathat containedRecords (#13139)unstable_SerializesTo- see the note in theUnstable Changessection below for more information@react-router/dev- Fix support for custom clientbuild.rollupOptions.output.entryFileNames(#13098)@react-router/dev- Fix usage ofprerenderoption whenserverBundlesoption has been configured or provided by a preset, e.g.vercelPresetfrom@vercel/react-router(#13082)@react-router/dev- Fix support for custombuild.assetsDir(#13077)@react-router/dev- Remove unused dependencies (#13134)@react-router/dev- Stub all routes except root in "SPA Mode" server builds to avoid issues when route modules or their dependencies import non-SSR-friendly modules (#13023)@react-router/dev- Remove unused Vite file system watcher (#13133)@react-router/dev- Fix support for custom SSR build input whenserverBundlesoption has been configured (#13107)future.unstable_viteEnvironmentApiandserverBundlesoptions together, hyphens are no longer supported in server bundle IDs since they also need to be valid Vite environment names.@react-router/dev- Fix dev server when using HTTPS by stripping HTTP/2 pseudo headers from dev server requests (#12830)@react-router/dev- Lazy load Cloudflare platform proxy on first dev server request when using thecloudflareDevProxyVite plugin to avoid creating unnecessaryworkerdprocesses (#13016)@react-router/dev- Fix duplicated entries in typegen for layout routes and their corresponding index route (#13140)@react-router/express- UpdateexpresspeerDependencyto include v5 (#13064) (#12961)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Addcontextsupport to client side data routers (unstable) (#12941)react-router- Support middleware on routes (unstable) (#12941)@react-router/dev- Fix errors withfuture.unstable_viteEnvironmentApiwhen thessrenvironment has been configured by another plugin to be a customVite.DevEnvironmentrather than the defaultVite.RunnableDevEnvironment(#13008)@react-router/dev- Whenfuture.unstable_viteEnvironmentApiis enabled and thessrenvironment hasoptimizeDeps.noDiscoverydisabled, defineoptimizeDeps.entriesandoptimizeDeps.include(#13007)Client-side
context(unstable)Your application
clientLoader/clientActionfunctions (orloader/actionin library mode) will now receive acontextparameter on the client. This is an instance ofunstable_RouterContextProviderthat you use with type-safe contexts (similar toReact.createContext) and is most useful with the correspondingunstable_clientMiddlewareAPI:Similar to server-side requests, a fresh
contextwill be created per navigation (orfetchercall). If you have initial data you'd like to populate in the context for every request, you can provide anunstable_getContextfunction at the root of your app:createBrowserRouter(routes, { unstable_getContext })<HydratedRouter unstable_getContext>This function should return an value of type
unstable_InitialContextwhich is aMap<unstable_RouterContext, unknown>of context's and initial values:Middleware (unstable)
Middleware is implemented behind a
future.unstable_middlewareflag. To enable, you must enable the flag and the types in yourreact-router.config.tsfile:⚠️ Middleware is unstable and should not be adopted in production. There is at least one known de-optimization in route module loading for
clientMiddlewarethat we will be addressing this before a stable release.⚠️ Enabling middleware contains a breaking change to the
contextparameter passed to yourloader/actionfunctions - see below for more information.Once enabled, routes can define an array of middleware functions that will run sequentially before route handlers run. These functions accept the same parameters as
loader/actionplus an additionalnextparameter to run the remaining data pipeline. This allows middlewares to perform logic before and after handlers execute.Here's a simple example of a client-side logging middleware that can be placed on the root route:
Note that in the above example, the
next/middlewarefunctions don't return anything. This is by design as on the client there is no "response" to send over the network like there would be for middlewares running on the server. The data is all handled behind the scenes by the statefulrouter.For a server-side middleware, the
nextfunction will return the HTTPResponsethat React Router will be sending across the wire, thus giving you a chance to make changes as needed. You may throw a new response to short circuit and respond immediately, or you may return a new or altered response to override the default returned bynext().You can throw a
redirectfrom a middleware to short circuit any remaining processing:Note that in cases like this where you don't need to do any post-processing you don't need to call the
nextfunction or return aResponse.Here's another example of using a server middleware to detect 404s and check the CMS for a redirect:
For more information on the
middlewareAPI/design, please see the decision doc.Middleware
contextparameterWhen middleware is enabled, your application will use a different type of
contextparameter in your loaders and actions to provide better type safety. Instead ofAppLoadContext,contextwill now be an instance ofContextProviderthat you can use with type-safe contexts (similar toReact.createContext):If you are using a custom server with a
getLoadContextfunction, the return value for initial context values passed from the server adapter layer is no longer an object and should now return anunstable_InitialContext(Map<RouterContext, unknown>):unstable_SerializesTounstable_SerializesToadded a way to register custom serialization types in Single Fetch for other library and framework authors like Apollo. It was implemented with branded type whose branded property that was made optional so that casting arbitrary values was easy:However, this broke type inference in
loaderDataandactionDatafor anyRecordtypes as those would now (incorrectly) matchunstable_SerializesTo. This affected all users, not just those that depended onunstable_SerializesTo. To fix this, the branded property ofunstable_SerializesTois marked as required instead of optional.For library and framework authors using
unstable_SerializesTo, you may need to addas unknowncasts before casting tounstable_SerializesTo.Changes by Package
create-react-routerreact-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v7.2.0...v7.3.0v7.2.0Compare Source
Date: 2025-02-18
What's Changed
Type-safe
hrefutilityIn framework mode, we now provide you with a fully type-safe
hrefutility to give you all the warm and fuzzy feelings of path auto-completion and param validation for links in your application:You'll now get type errors if you pass a bad path value or a bad param value:
Prerendering with a SPA Fallback
This release enhances the ability to use a combination of pre-rendered paths alongside other paths that operate in "SPA Mode" when pre-rendering with
ssr:false.ssr:falsewithout aprerenderconfig, this is considered "SPA Mode" and the generatedindex.htmlfile will only render down to the root route and will be able to hydrate for any valid application pathssr:falsewith aprerenderconfig but do not include the/path (i.e.,prerender: ['/blog/post']), then we still generate a "SPA Mode"index.htmlfile that can hydrate for any path in the applicationssr:falseand include the/path in yourprerenderconfig, the generatedindex.htmlfile will be specific to the root index route, so we will now also generate a separate "SPA Mode" file in__spa-fallback.htmlthat you can serve/hydrate for non-prerendered pathsFor more info, see the Pre-rendering docs for more info.
Allow a root
loaderin SPA ModeSPA Mode used to prohibit the use of loaders in all routes so that we could hydrate for any path in the application. However, because the root route is always rendered at build time, we can lift this restriction for the root route.
In order to use your build-time loader data during pre-rendering, we now also expose the
loaderDataas an optional prop for theHydrateFallbackcomponent on routes:HydrateFallbackis rendering because children routes are loadingundefinedif theHydrateFallbackis rendering because the route itself has it's own hydratingclientLoaderMinor Changes
react-router- New type-safehrefutility that guarantees links point to actual paths in your app (#13012)@react-router/dev- Generate a "SPA fallback" HTML file when pre-rendering the/route withssr:false(#12948)@react-router/dev- Allow aloaderin the root route in SPA mode because it can be called/server-rendered at build time (#12948)Route.HydrateFallbackPropsnow also receivesloaderDataPatch Changes
react-router- Disable Lazy Route Discovery for allssr:falseapps and not just "SPA Mode" because there is no runtime server to serve the search-param-configured__manifestrequests (#12894)ssr:falseappsprerenderscenarios we would pre-render the/__manifestfile but that makes some unnecessary assumptions about the static file server behaviorsreact-router- Don't apply Single Fetch revalidation de-optimization when in SPA mode since there is no server HTTP request (#12948)react-router- Properly handle revalidations to across a pre-render/SPA boundary (#13021).datarequests if the path wasn't pre-rendered because the request will 404loaderdata inssr:falsemode is static because it's generated at build timeclientLoaderto do anything dynamicloaderand not aclientLoader, we disable revalidation by default because there is no new data to retrieve.datarequest logic if there are no server loaders withshouldLoad=truein our single fetchdataStrategy.datarequest that would 404 after a submissionreact-router- Align dev server behavior with static file server behavior whenssr:falseis set (#12948)prerenderconfig exists, only SSR down to the rootHydrateFallback(SPA Mode)prerenderconfig exists but the current path is not pre-rendered, only SSR down to the rootHydrateFallback(SPA Fallback).datarequests to non-pre-rendered pathsreact-router- Improve prefetch performance of CSS side effects in framework mode (#12889)react-router- Properly handle interrupted manifest requests in lazy route discovery (#12915)@react-router/dev- Handle customenvDirin Vite config (#12969)@react-router/dev- Fix CLI parsing to allow argument-lessnpx react-routerusage (#12925)@react-router/dev- Skip action-only resource routes when usingprerender:true(#13004)@react-router/dev- Enhance invalid export detection when usingssr:false(#12948)headers/actionfunctions are prohibited in all routes withssr:falsebecause there will be no runtime server on which to run themloaderfunctions are more nuanced and depend on whether a given route is prerenderedssr:falsewithout aprerenderconfig, only therootroute can have aloaderssr:falsewith aprerenderconfig, only routes matched by aprerenderpath can have aloader@react-router/dev- Error at build time inssr:false+prerenderapps for the edge case scenario of: (#13021)loader(does not have aclientLoader)loaderDatabecause there is no server on which to run theloaderclientLoaderor pre-rendering the child pathsclientLoader, calling theserverLoader()on non-prerendered paths will throw a 404@react-router/dev- Limit prerendered resource route.datafiles to only the target route (#13004)@react-router/dev- Fix pre-rendering of binary files (#13039)@react-router/dev- Fix typegen for repeated params (#13012)/a/:id/b/:id?/c/:id, the last:idwill set the value foridinuseParamsand theparamsprop/a/1/b/2/c/3will result in the value{ id: 3 }at runtime/a/1/b/2/c/3generated a type like{ id: [1,2,3] }./a/1/b/2/c/3now generates a type like{ id: 3 }.@react-router/dev- Fix path to loadpackage.jsonforreact-router --version(#13012)Unstable Changes
⚠️ Unstable features are not recommended for production use
react-router- Addunstable_SerializesTobrand type for library authors to register types serializable by React Router's streaming format (turbo-stream) (#12264)@react-router/dev- Add unstable support for splitting route modules in framework mode viafuture.unstable_splitRouteModules(#11871)@react-router/dev- Addfuture.unstable_viteEnvironmentApiflag to enable experimental Vite Environment API support (#12936)Split Route Modules (unstable)
One of the conveniences of the Route Module API is that everything a route needs is in a single file. Unfortunately this comes with a performance cost in some cases when using the
clientLoader,clientAction, andHydrateFallbackAPIs.As a basic example, consider this route module:
In this example we have a minimal
clientLoaderexport that makes a basic fetch call, whereas the default component export is much larger. This is a problem for performance because it means that if we want to navigate to this route client-side, the entire route module must be downloaded before the client loader can start running.To visualize this as a timeline:
In the following timeline diagrams, different characters are used within the Route Module bars to denote the different Route Module APIs being exported.
Instead, we want to optimize this to the following:
To achieve this optimization, React Router will split the route module into multiple smaller modules during the production build process. In this case, we'll end up with two separate virtual modules — one for the client loader and one for the component and its dependencies.
Now that these are available as separate modules, the client loader and the component can be downloaded in parallel. This means that the client loader can be executed as soon as it's ready without having to wait for the component.
This optimization is even more pronounced when more Route Module APIs are used. For example, when using
clientLoader,clientActionandHydrateFallback, the timeline for a single route module during a client-side navigation might look like this:This would instead be optimized to the following:
Note that this optimization only works when the Route Module APIs being split don't share code within the same file. For example, the following route module can't be split:
This route will still work, but since both the client loader and the component depend on the
sharedfunction defined within the same file, it will be de-optimized into a single route module.To avoid this, you can extract any code shared between exports into a separate file. For example:
You can then import this shared code in your route module without triggering the de-optimization:
Since the shared code is in its own module, React Router is now able to split this route module into two separate virtual modules:
If your project is particularly performance sensitive, you can set the
unstable_splitRouteModulesfuture flag to"enforce":This setting will raise an error if any route modules can't be split:
Changes by Package
create-react-routerreact-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v7.1.5...v7.2.0v7.1.5Compare Source
Date: 2025-01-31
Patch Changes
react-router- Fix regression introduced in7.1.4via #12800 that caused issues navigating to hash routes inside splat routes for applications using Lazy Route Discovery (patchRoutesOnNavigation) (#12927)Full Changelog:
v7.1.4...v7.1.5v7.1.4Compare Source
Date: 2025-01-30
Patch Changes
@react-router/dev- Properly resolve Windows file paths to scan for Vite's dependency optimization when using theunstable_optimizeDepsfuture flag (#12637)@react-router/dev- Fix prerendering when using a custom server - previously we ended up trying to import the users custom server when we actually want to import the virtual server build module (#12759)react-router- Properly handle status codes that cannot have a body in single fetch responses (204, etc.) (#12760)react-router- Properly bubble headers aserrorHeaderswhen throwing adata()result (#12846)Set-Cookieheaders if also returned fromheadersreact-router- Stop erroring on resource routes that return raw strings/objects and instead serialize them astext/plainorapplication/jsonresponses (#12848).dataextension.datarequest, they will still be encoded viaturbo-streamreact-router- Optimize Lazy Route Discovery path discovery to favor a singlequerySelectorAllcall at thebodylevel instead of many calls at the sub-tree level (#12731)react-router- Optimize route matching by skipping redundantmatchRoutescalls when possible (#12800, #12882)react-router- Internal reorg to clean up some duplicated route module types (#12799)Full Changelog:
v7.1.3...v7.1.4v7.1.3Compare Source
Date: 2025-01-17
Patch Changes
@react-router/dev- FixrevealandroutesCLI commands (#12745)Full Changelog:
v7.1.2...v7.1.3v7.1.2Compare Source
Date: 2025-01-16
Patch Changes
react-router- Fix issue with fetcher data cleanup in the data layer on fetcher unmount (#12681)react-router- Do not rely onsymbolfor filtering outredirectresponses from loader data (#12694)symbols are not used for theredirectresponse type, these errors should no longer be present@react-router/dev- Fix default external conditions in Vite v6 (#12644)@react-router/dev- Fix mismatch in prerendering html/data files when path is missing a leading slash (#12684)@react-router/dev- Usemodule-syncserver condition when enabled in the runtime. This fixes React context mismatches (e.g.useHref() may be used only in the context of a <Router> component.) during development on Node 22.10.0+ when using libraries that have a peer dependency on React Router (#12729)@react-router/dev- Fixreact-refreshsource maps (#12686)Full Changelog:
v7.1.1...v7.1.2v7.1.1Compare Source
Date: 2024-12-23
Patch Changes
@react-router/dev- Fix for a crash when optional args are passed to the CLI (#12609)Full Changelog:
v7.1.0...v7.1.1v7.1.0Compare Source
Date: 2024-12-20
Minor Changes
Patch Changes
react-router- Throw unwrapped Single Fetchredirectto align with pre-Single Fetch behavior (#12506)react-router- Ignore redirects when inferring loader data types (#12527)react-router- Remove<Link prefetch>warning which suffers from false positives in a lazy route discovery world (#12485)create-react-router- Fix missingfs-extradependency (#12556)@react-router/dev/@react-router/serve- Properly initializeNODE_ENVif not already set for compatibility with React 19 (#12578)@react-router/dev- Remove the leftover/unusedabortDelayprop fromServerRouterand update the defaultentry.server.tsxto use the newstreamTimeoutvalue for Single Fetch (#12478)abortDelayfunctionality was removed in v7 as it was coupled to thedeferimplementation from Remix v2, but this removal of this prop was missedentry.serverfile, it's likely your app is not aborting streams as you would expect and you will need to adopt the newstreamTimeoutvalue introduced with Single Fetch@react-router/fs-routes- Throw error inflatRoutesif routes directory is missing (#12407)Changes by Package
create-react-routerreact-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v7.0.2...v7.1.0v7.0.2Compare Source
Date: 2024-12-02
Patch Changes
react-router- Temporarily only use one build in export map so packages can have a peer dependency on react router (#12437)@react-router/dev- SupportmoduleResolutionNode16andNodeNext(#12440)@react-router/dev- Generate widematchesandparamstypes for child routes (#12397)matchesincludes child route matches andparamsinclude child route path parametersmatchesandparamsFull Changelog:
v7.0.1...v7.0.2v7.0.1Compare Source
Date: 2024-11-22
Patch Changes
@react-router/dev- Ensure typegen file watcher is cleaned up when Vite dev server restarts (#12331)@react-router/dev- Pass routeerrortoErrorBoundaryas a prop (#12338)Full Changelog:
v7.0.0...v7.0.1v7.0.0Compare Source
Date: 2024-11-21
Breaking Changes
Package Restructuring
react-router-dom,@remix-run/react,@remix-run/server-runtime, and@remix-run/routerhave been collapsed into thereact-routerpackagereact-router-domis still published in v7 as a re-export of everything fromreact-router@remix-run/cloudflare-pagesand@remix-run/cloudflare-workershave been collapsed into@react-router/cloudflarepackage`react-router-dom-v5-compatandreact-router-nativepackages are removed starting with v7Removed Adapter Re-exports
Remix v2 used to re-export all common
@remix-run/server-runtimeAPIs through the various runtime packages (node,cloudflare,deno) so that you wouldn't need an additional@remix-run/server-runtimedependency in yourpackage.json. With the collapsing of packages intoreact-router, these common APIs are now no longer re-exported through the runtime adapters. You should import all common APIs fromreact-router, and only import runtime-specific APIs from the runtime packages:Removed APIs
The following APIs have been removed in React Router v7:
jsondeferunstable_composeUploadHandlersunstable_createMemoryUploadHandlerunstable_parseMultipartFormDataMinimum Versions
React Router v7 requires the following minimum versions:
node@20installGlobalsmethod to polyfill thefetchAPIreact@18,react-dom@18Adopted Future Flag Behaviors
Remix and React Router follow an API Development Strategy leveraging "Future Flags" to avoid introducing a slew of breaking changes in a major release. Instead, breaking changes are introduced in minor releases behind a flag, allowing users to opt-in at their convenience. In the next major release, all future flag behaviors become the default behavior.
The following previously flagged behaviors are now the default in React Router v7:
future.v7_relativeSplatPathfuture.v7_startTransitionfuture.v7_fetcherPersistfuture.v7_normalizeFormMethodfuture.v7_partialHydrationfuture.v7_skipActionStatusRevalidationfuture.v3_fetcherPersistfuture.v3_relativeSplatPathfuture.v3_throwAbortReasonfuture.v3_singleFetchfuture.v3_lazyRouteDiscoveryfuture.v3_optimizeDepsVite Compiler
The Remix Vite plugin is the proper way to build full-stack SSR apps using React Router v7. The former
esbuild-based compiler is no longer available.Renamed
vitePluginandcloudflareDevProxyVitePluginFor Remix consumers migrating to React Router, the
vitePluginandcloudflareDevProxyVitePluginexports have been renamed and moved (#11904)Removed
manifestoptionFor Remix consumers migrating to React Router, the Vite plugin's
manifestoption has been removed. Themanifestoption been superseded by the more powerfulbuildEndhook since it's passed thebuildManifestargument. You can still write the build manifest to disk if needed, but you'll most likely find it more convenient to write any logic depending on the build manifest within thebuildEndhook itself. (#11573)If you were using the
manifestoption, you can replace it with abuildEndhook that writes the manifest to disk like this:Exposed Router Promises
Because React 19 will have first-class support for handling promises in the render pass (via
React.useanduseAction), we are now comfortable exposing the promises for the APIs that previously returnedundefined:useNavigate()useSubmit()useFetcher().loaduseFetcher().submituseRevalidator().revalidate()Other Notable Changes
routes.tsWhen using the React Router Vite plugin, routes are defined in
app/routes.ts. Route config is exported via theroutesexport, conforming to theRouteConfigtype. Route helper functionsroute,index, andlayoutare provided to make declarative type-safe route definitions easier.For Remix consumers migrating to React Router, you can still configure file system routing within
routes.tsusing the@react-router/fs-routespackage. A minimal route config that reproduces the default Remix setup looks like this:If you want to migrate from file system routing to config-based routes, you can mix and match approaches by spreading the results of the async
flatRoutesfunction into the array of config-based routes.If you were using Remix's
routesoption to use alternative file system routing conventions, you can adapt these to the newRouteConfigformat using@react-router/remix-config-routes-adapter.For example, if you were using Remix v1 route conventions in Remix v2, you can combine
@react-router/remix-config-routes-adapterwith@remix-run/v1-route-conventionto adapt this to React Router:Also note that, if you were using Remix's
routesoption to define config-based routes, you can also adapt these to the newRouteConfigformat using@react-router/remix-config-routes-adapterwith minimal code changes. While this makes for a fast migration path, we recommend migrating any config-based routes from Remix to the newRouteConfigformat since it's a fairly straightforward migration.Type-safety improvements
React Router now generates types for each of your route modules and passes typed props to route module component exports (#11961, #12019). You can access those types by importing them from
./+types/<route filename without extension>.See How To > Route Module Type Safety and Explanations > Type Safety for more details.
Prerendering
React Router v7 includes a new
prerenderconfig in the vite plugin to support SSG use-cases. This will pre-render your.htmland.datafiles at build time and so you can serve them statically at runtime from a running server or a CDN (#11539)Major Changes (
react-router)deferimplementation in favor of using raw promises via single fetch andturbo-stream(#11744)deferAbortedDeferredErrortype TypedDeferredDataUNSAFE_DeferredDataUNSAFE_DEFERRED_SYMBOLreact-router(#11505)@remix-run/routerreact-router-dom@remix-run/server-runtime@remix-run/testingreact-router-dompackage is maintained to ease adoption but it simply re-exports all APIs fromreact-routerfuture.v7_startTransitionflag (#11696)future.v7_normalizeFormMethodfuture flag (#11697)@remix-run/routerAgnosticDataIndexRouteObjectAgnosticDataNonIndexRouteObjectAgnosticDataRouteMatchAgnosticDataRouteObjectAgnosticIndexRouteObjectAgnosticNonIndexRouteObjectAgnosticRouteMatchAgnosticRouteObjectTrackedPromiseunstable_AgnosticPatchRoutesOnMissFunctionAction-> exported asNavigationTypeviareact-routerRouterexported asRemixRouterto differentiate from RR's<Router>getToPathname(@private)joinPaths(@private)normalizePathname(@private)resolveTo(@private)stripBasename(@private)createBrowserHistory-> in favor ofcreateBrowserRoutercreateHashHistory-> in favor ofcreateHashRoutercreateMemoryHistory-> in favor ofcreateMemoryRoutercreateRoutercreateStaticHandler-> in favor of wrappercreateStaticHandlerin RR DomgetStaticContextFromErrorreact-routerHashPathnameSearchfuture.v7_prependBasenamefrom the internalized@remix-run/routerpackage (#11726)future.v7_throwAbortReasonfrom internalized@remix-run/routerpackage (#11728)exportsfield to all packages (#11675)RemixContexttoFrameworkContext(#11705)PrefetchPageDescriptorreplaced byPageLinkDescriptor(#11960)future.v7_partialHydrationflag (#11725)<RouterProvider fallbackElement>propfallbackElementto ahydrateFallbackElement/HydrateFallbackon your root routefuture.v7_partialHydration(when usingfallbackElement),state.navigationwas populated during the initial loadfuture.v7_partialHydration,state.navigationremains in an"idle"state during the initial loadfuture.v7_relativeSplatPathfuture flag (#11695)v7_skipActionErrorRevalidationv3_fetcherPersist,v3_relativeSplatPath,v3_throwAbortReasoncreateRemixStubtocreateRoutesStub(#11692)@remix-run/routerdeprecateddetectErrorBoundaryoption in favor ofmapRouteProperties(#11751)react-router/domsubpath export to properly enablereact-domas an optionalpeerDependency(#11851)import ReactDOM from "react-dom"in<RouterProvider>in order to accessReactDOM.flushSync(), since that would breakcreateMemoryRouteruse cases in non-DOM environmentsreact-router/domto get the proper component that makesReactDOM.flushSync()available:entry.client.tsx:import { HydratedRouter } from 'react-router/dom'createBrowserRouter/createHashRouter:import { RouterProvider } from "react-router/dom"future.v7_fetcherPersistflag (#11731)undefinedfrom loaders and actions (#11680, #12057)createRemixRouter/RouterProviderinentry.clientinstead ofRemixBrowser(#11469)jsonutility (#12146)Response.jsonif you still need to construct JSON responses in your appMajor Changes (
@react-router/*)future.v3_singleFetchflag (#11522)installGlobals()as this should no longer be necessaryexportsfield to all packages (#11675)react-routerthrough different runtime/adapter packages (#11702)cryptoglobal from the Web Crypto API is now required when using cookie and session APIsreact-routerrather than platform-specific packages: (#11837)createCookiecreateCookieSessionStoragecreateMemorySessionStoragecreateSessionStorageinstallGlobalsfunction from@remix-run/nodehas been updated to defineglobalThis.crypto, using Node'srequire('node:crypto').webcryptoimplementationcreateCookieFactorycreateSessionStorageFactorycreateCookieSessionStorageFactorycreateMemorySessionStorageFactory@remix-run/router,@remix-run/server-runtime, and@remix-run/reactnow that they all live inreact-router(#12177)LoaderFunction,LoaderFunctionArgs,ActionFunction,ActionFunctionArgs,DataFunctionArgs,RouteManifest,LinksFunction,Route,EntryRouteRouteManifesttype used by the "remix" code is now slightly stricter because it is using the former@remix-run/routerRouteManifestRecord<string, Route> -> Record<string, Route | undefined>AppDatatype in favor of inliningunknownin the few locations it was usedServerRuntimeMeta*types in favor of theMeta*types they were duplicated fromRoute.*typesRoute.*typesuseFetcherpreviously had an optional generic (used primarily by Remix v2) that expected the data typetypeof loader/typeof action)useFetcher<LoaderData>()useFetcher<typeof loader>()cookiedependency to^1.0.1- please see the release notes for any breaking changes (#12172)@react-router/cloudflare- For Remix consumers migrating to React Router, all exports from@remix-run/cloudflare-pagesare now provided for React Router consumers in the@react-router/cloudflarepackage. There is no longer a separate package for Cloudflare Pages. (#11801)@react-router/cloudflare- The@remix-run/cloudflare-workerspackage has been deprecated. Remix consumers migrating to React Router should use the@react-router/cloudflarepackage directly. For guidance on how to use@react-router/cloudflarewithin a Cloudflare Workers context, refer to the Cloudflare Workers template. (#11801)@react-router/dev- For Remix consumers migrating to React Router, thevitePluginandcloudflareDevProxyVitePluginexports have been renamed and moved. (#11904)@react-router/dev- For Remix consumers migrating to React Router who used the Vite plugin'sbuildEndhook, the resolvedreactRouterConfigobject no longer contains apublicPathproperty since this belongs to Vite, not React Router (#11575)@react-router/dev- For Remix consumers migrating to React Router, the Vite plugin'smanifestoption has been removed (#11573)@react-router/dev- Update defaultisbotversion to v5 and drop support forisbot@3(#11770)isbot@4orisbot@5in yourpackage.json:isbot@3in yourpackage.jsonand you have your ownentry.server.tsxfile in your repoisbot@5independent of the React Router v7 upgradeisbot@3in yourpackage.jsonand you do not have your ownentry.server.tsxfile in your repoisbot@5in yourpackage.json@react-router/dev- For Remix consumers migrating to React Router, Vite manifests (i.e..vite/manifest.json) are now written within each build subdirectory, e.g.build/client/.vite/manifest.jsonandbuild/server/.vite/manifest.jsoninstead ofbuild/.vite/client-manifest.jsonandbuild/.vite/server-manifest.json. This means that the build output is now much closer to what you'd expect from a typical Vite project. (#11573)build/.vitedirectory to avoid accidentally serving them in production, particularly from the client build. This was later improved with additional logic that deleted these Vite manifest files at the end of the build process unless Vite'sbuild.manifesthad been enabled within the app's Vite config. This greatly reduced the risk of accidentally serving the Vite manifests in production since they're only present when explicitly asked for. As a result, we can now assume that consumers will know that they need to manage these additional files themselves, and React Router can safely generate a more standard Vite build output.Minor Changes
react-router- Params, loader data, and action data as props for route component exports (#11961)react-router- Add route module type generation (#12019)react-router- Remove duplicateRouterProviderimplementations (#11679)react-router- Stabilizeunstable_dataStrategy(#11969)react-router- Stabilizeunstable_patchRoutesOnNavigation(#11970)react-router- Add prefetching support toLink/NavLinkwhen using Remix SSR (#11402)react-router- EnhanceScrollRestorationso it can restore properly on an SSR'd document load (#11401)@react-router/dev- Add support for theprerenderconfig in the React Router vite plugin, to support existing SSG use-cases (#11539)@react-router/dev- Remove internalentry.server.spa.tsximplementation which was not compatible with the Single Fetch async hydration approach (#11681)@react-router/serve: Updateexpress.staticconfigurations to support newprerenderAPI (#11547)build/client/assetsfolder are served as before, with a 1-year immutableCache-Controlheader.htmland.datafiles are not served with a specificCache-Controlheader.datafiles are served withContent-Type: text/x-turboexpress.static, it seems to also add aCache-Control: public, max-age=0to.datafilesPatch Changes
substrwithsubstring(#12080)react-router- Fix redirects returned from loaders/actions usingdata()(#12021)@react-router/dev- Enable prerendering for resource routes (#12200)@react-router/dev- resolve config directory relative to flat output file structure (#12187)Changes by Package
react-router@react-router/architect@react-router/cloudflare@react-router/dev@react-router/express@react-router/fs-routes@react-router/node@react-router/remix-config-routes-adapter@react-router/serveFull Changelog:
v6.28.0...v7.0.0Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate.
b61167e8f49fe5f4614a