fix(deps): update react-router monorepo to v6.22.3 #3
Reference in New Issue
Block a user
Delete Branch "renovate/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.0.0-beta.0->6.22.36.0.0-beta.0->6.22.3Release Notes
remix-run/react-router (react-router)
v6.22.3Compare Source
Patch Changes
@remix-run/router@1.15.3v6.22.2Compare Source
Patch Changes
@remix-run/router@1.15.2v6.22.1Compare Source
Patch Changes
@remix-run/router@1.15.1v6.22.0Compare Source
Patch Changes
@remix-run/router@1.15.0v6.21.3Compare Source
Patch Changes
unstable_prefix fromBlocker/BlockerFunctiontypes (#11187)v6.21.2Compare Source
Patch Changes
@remix-run/router@1.14.2v6.21.1Compare Source
Patch Changes
route.lazynot working correctly on initial SPA load whenv7_partialHydrationis specified (#11121)@remix-run/router@1.14.1v6.21.0Compare Source
Minor Changes
Add a new
future.v7_relativeSplatPathflag to implement a breaking bug fix to relative routing when inside a splat route. (#11087)This fix was originally added in #10983 and was later reverted in #11078 because it was determined that a large number of existing applications were relying on the buggy behavior (see #11052)
The Bug
The buggy behavior is that without this flag, the default behavior when resolving relative paths is to ignore any splat (
*) portion of the current route path.The Background
This decision was originally made thinking that it would make the concept of nested different sections of your apps in
<Routes>easier if relative routing would replace the current splat:Any paths like
/dashboard,/dashboard/team,/dashboard/projectswill match theDashboardroute. The dashboard component itself can then render nested<Routes>:Now, all links and route paths are relative to the router above them. This makes code splitting and compartmentalizing your app really easy. You could render the
Dashboardas its own independent app, or embed it into your large app without making any changes to it.The Problem
The problem is that this concept of ignoring part of a path breaks a lot of other assumptions in React Router - namely that
"."always means the current location pathname for that route. When we ignore the splat portion, we start getting invalid paths when using".":We've also introduced an issue that we can no longer move our
DashboardTeamcomponent around our route hierarchy easily - since it behaves differently if we're underneath a non-splat route, such as/dashboard/:widget. Now, our"."links will, properly point to ourself inclusive of the dynamic param value so behavior will break from it's corresponding usage in a/dashboard/*route.Even worse, consider a nested splat route configuration:
Now, a
<Link to=".">and a<Link to="..">inside theDashboardcomponent go to the same place! That is definitely not correct!Another common issue arose in Data Routers (and Remix) where any
<Form>should post to it's own routeactionif you the user doesn't specify a form action:This is just a compounded issue from the above because the default location for a
Formto submit to is itself (".") - and if we ignore the splat portion, that now resolves to the parent route.The Solution
If you are leveraging this behavior, it's recommended to enable the future flag, move your splat to it's own route, and leverage
../for any links to "sibling" pages:This way,
.means "the full current pathname for my route" in all cases (including static, dynamic, and splat routes) and..always means "my parents pathname".Patch Changes
@remix-run/router@1.14.0v6.20.1Compare Source
Patch Changes
useResolvedPathfix for splat routes due to a large number of applications that were relying on the buggy behavior (see #11052 (comment)). We plan to re-introduce this fix behind a future flag in the next minor version. (#11078)@remix-run/router@1.13.1v6.20.0Compare Source
Minor Changes
PathParamtype from the public API (#10719)Patch Changes
resolveToin splat routes (#11045)getPathContributingMatchesUNSAFE_getPathContributingMatchesexport from@remix-run/routersince we no longer need this in thereact-router/react-router-domlayers@remix-run/router@1.13.0v6.19.0Compare Source
Minor Changes
unstable_flushSyncoption touseNavigate/useSumbit/fetcher.load/fetcher.submitto opt-out ofReact.startTransitionand intoReactDOM.flushSyncfor state updates (#11005)unstable_prefix from theuseBlockerhook as it's been in use for enough time that we are confident in the API. We do not plan to remove the prefix fromunstable_usePromptdue to differences in how browsers handlewindow.confirmthat prevent React Router from guaranteeing consistent/correct behavior. (#10991)Patch Changes
Fix
useActionDataso it returns proper contextual action data and not any action data in the tree (#11023)Fix bug in
useResolvedPaththat would causeuseResolvedPath(".")in a splat route to lose the splat portion of the URL path. (#10983)"."paths inside a splat route which incorrectly dropped the splat portion of the URL. If you are relative routing via"."inside a splat route in your application you should double check that your logic is not relying on this buggy behavior and update accordingly.Updated dependencies:
@remix-run/router@1.12.0v6.18.0Compare Source
Patch Changes
futureprop onBrowserRouter,HashRouterandMemoryRouterso that it accepts aPartial<FutureConfig>instead of requiring all flags to be included. (#10962)@remix-run/router@1.11.0v6.17.0Compare Source
Patch Changes
RouterProviderfutureprop type to be aPartial<FutureConfig>so that not all flags must be specified (#10900)@remix-run/router@1.10.0v6.16.0Compare Source
Minor Changes
anywithunknownon exposed typings for user-provided data. To do this in Remix v2 without introducing breaking changes in React Router v6, we have added generics to a number of shared types. These continue to default toanyin React Router and are overridden withunknownin Remix. In React Router v7 we plan to move these tounknownas a breaking change. (#10843)Locationnow accepts a generic for thelocation.statevalueActionFunctionArgs/ActionFunction/LoaderFunctionArgs/LoaderFunctionnow accept a generic for thecontextparameter (only used in SSR usages viacreateStaticHandler)useMatches(now exported asUIMatch) accepts generics formatch.dataandmatch.handle- both of which were already set tounknown@privateclass exportErrorResponseto anUNSAFE_ErrorResponseImplexport since it is an implementation detail and there should be no construction ofErrorResponseinstances in userland. This frees us up to export atype ErrorResponsewhich correlates to an instance of the class viaInstanceType. Userland code should only ever be usingErrorResponseas a type and should be type-narrowing viaisRouteErrorResponse. (#10811)ShouldRevalidateFunctionArgsinterface (#10797)_isFetchActionRedirect,_hasFetcherDoneAnything) (#10715)Patch Changes
@remix-run/router@1.9.0v6.15.0Compare Source
Minor Changes
redirectDocument()function which allows users to specify that a redirect from aloader/actionshould trigger a document reload (viawindow.location) instead of attempting to navigate to the redirected location via React Router (#10705)Patch Changes
useRevalidatoris referentially stable across re-renders if revalidations are not actively occurring (#10707)@remix-run/router@1.8.0v6.14.2Compare Source
Patch Changes
@remix-run/router@1.7.2v6.14.1Compare Source
Patch Changes
unstable_useBlockerwhen used with an unstable blocker function (#10652)@remix-run/router@1.7.1v6.14.0Compare Source
Patch Changes
basenamefrom locations provided tounstable_useBlockerfunctions to matchuseLocation(#10573)generatePathwhen passed a numeric0value parameter (#10612)unstable_useBlockerkey issues inStrictMode(#10573)tsc --skipLibCheck:falseissues on React 17 (#10622)typescriptto 5.1 (#10581)@remix-run/router@1.7.0v6.13.0Compare Source
Minor Changes
Move
React.startTransitionusage behind a future flag to avoid issues with existing incompatibleSuspenseusages. We recommend folks adopting this flag to be better compatible with React concurrent mode, but if you run into issues you can continue without the use ofstartTransitionuntil v7. Issues usually boils down to creating net-new promises during the render cycle, so if you run into issues you should either lift your promise creation out of the render cycle or put it behind auseMemo. (#10596)Existing behavior will no longer include
React.startTransition:If you wish to enable
React.startTransition, pass the future flag to your component:Patch Changes
React.startTransitionminification bug in production mode (#10588)v6.12.1Compare Source
Patch Changes
React.startTransitionto fix webpack + react 17 compilation error (#10569)v6.12.0Compare Source
Minor Changes
React.startTransitionif it exists (#10438)Patch Changes
@remix-run/router@1.6.3v6.11.2Compare Source
Patch Changes
basenameduplication in descendant<Routes>inside a<RouterProvider>(#10492)@remix-run/router@1.6.2v6.11.1Compare Source
Patch Changes
ComponentAPI within descendant<Routes>(#10434)useNavigatefrom<Routes>inside a<RouterProvider>(#10432)<Navigate>in strict mode when using a data router (#10435)@remix-run/router@1.6.1v6.11.0Compare Source
Patch Changes
<Routes>whenRouterProvidererrors existed (#10374)Componentinstead ofelementon a route definition (#10287)useNavigatein the render cycle by setting theactiveRefin a layout effect, allowing thenavigatefunction to be passed to child components and called in auseEffectthere. (#10394)useSyncExternalStoretouseStatefor internal@remix-run/routerrouter state syncing in<RouterProvider>. We found some subtle bugs where router state updates got propagated before other normaluseStateupdates, which could lead to footguns inuseEffectcalls. (#10377, #10409)useRevalidator()to resolve a loader-driven error boundary scenario (#10369)RouterProvider,useNavigate/useSubmit/fetcher.submitare now stable across location changes, since we can handle relative routing via the@remix-run/routerinstance and get rid of our dependence onuseLocation(). When usingBrowserRouter, these hooks remain unstable across location changes because they still rely onuseLocation(). (#10336)@remix-run/router@1.6.0v6.10.0Compare Source
Minor Changes
Added support for Future Flags in React Router. The first flag being introduced is
future.v7_normalizeFormMethodwhich will normalize the exposeduseNavigation()/useFetcher()formMethodfields as uppercase HTTP methods to align with thefetch()behavior. (#10207)future.v7_normalizeFormMethod === false(default v6 behavior),useNavigation().formMethodis lowercaseuseFetcher().formMethodis lowercasefuture.v7_normalizeFormMethod === true:useNavigation().formMethodis uppercaseuseFetcher().formMethodis uppercasePatch Changes
createRoutesFromElements(#10193)@remix-run/router@1.5.0v6.9.0Compare Source
Minor Changes
React Router now supports an alternative way to define your route
elementanderrorElementfields as React Components instead of React Elements. You can instead pass a React Component to the newComponentandErrorBoundaryfields if you choose. There is no functional difference between the two, so use whichever approach you prefer 😀. You shouldn't be defining both, but if you doComponent/ErrorBoundarywill "win". (#10045)Example JSON Syntax
Example JSX Syntax
Introducing Lazy Route Modules! (#10045)
In order to keep your application bundles small and support code-splitting of your routes, we've introduced a new
lazy()route property. This is an async function that resolves the non-route-matching portions of your route definition (loader,action,element/Component,errorElement/ErrorBoundary,shouldRevalidate,handle).Lazy routes are resolved on initial load and during the
loadingorsubmittingphase of a navigation or fetcher call. You cannot lazily define route-matching properties (path,index,children) since we only execute your lazy route functions after we've matched known routes.Your
lazyfunctions will typically return the result of a dynamic import.Then in your lazy route modules, export the properties you want defined for the route:
An example of this in action can be found in the
examples/lazy-loading-router-providerdirectory of the repository.🙌 Huge thanks to @rossipedia for the Initial Proposal and POC Implementation.
Updated dependencies:
@remix-run/router@1.4.0Patch Changes
generatePathincorrectly applying parameters in some cases (#10078)v6.8.2Compare Source
Patch Changes
@remix-run/router@1.3.3v6.8.1Compare Source
Patch Changes
@remix-run/router@1.3.2v6.8.0Compare Source
Patch Changes
@remix-run/router@1.3.1v6.7.0Compare Source
Minor Changes
unstable_useBlockerhook for blocking navigations within the app's location origin (#9709)Patch Changes
generatePathwhen optional params are present (#9764)<Await>to acceptReactNodeas children function return result (#9896)@remix-run/router@1.3.0v6.6.2Compare Source
Patch Changes
useIdconsistency during SSR (#9805)v6.6.1Compare Source
Patch Changes
@remix-run/router@1.2.1v6.6.0Compare Source
Patch Changes
useLoaderDatausage inerrorElement(#9735)@remix-run/router@1.2.0v6.5.0Compare Source
This release introduces support for Optional Route Segments. Now, adding a
?to the end of any path segment will make that entire segment optional. This works for both static segments and dynamic parameters.Optional Params Examples
<Route path=":lang?/about>will match:/:lang/about/about<Route path="/multistep/:widget1?/widget2?/widget3?">will match:/multistep/multistep/:widget1/multistep/:widget1/:widget2/multistep/:widget1/:widget2/:widget3Optional Static Segment Example
<Route path="/home?">will match://home<Route path="/fr?/about">will match:/about/fr/aboutMinor Changes
Patch Changes
<Route path="prefix-:param">, to align with how splat parameters work. If you were previously relying on this behavior then it's recommended to extract the static portion of the path at theuseParamscall site: (#9506)@remix-run/router@1.1.0v6.4.5Compare Source
Patch Changes
@remix-run/router@1.0.5v6.4.4Compare Source
Patch Changes
@remix-run/router@1.0.4v6.4.3Compare Source
Patch Changes
useRoutesshould be able to returnnullwhen passinglocationArg(#9485)initialEntriestype increateMemoryRouter(#9498)@remix-run/router@1.0.3v6.4.2Compare Source
Patch Changes
IndexRouteObjectandNonIndexRouteObjecttypes to makehasErrorElementoptional (#9394)RouteObject/RoutePropstypes to surface the error in TypeScript. (#9366)@remix-run/router@1.0.2v6.4.1Compare Source
Patch Changes
initialEntries(#9288)@remix-run/router@1.0.1v6.4.0Compare Source
Whoa this is a big one!
6.4.0brings all the data loading and mutation APIs over from Remix. Here's a quick high level overview, but it's recommended you go check out the docs, especially the feature overview and the tutorial.New APIs
createMemoryRouter<RouterProvider>loaderand mutate with a RouteactionerrorElementdeferandAwaitBug Fixes
useLocationreturns the scoped location inside a<Routes location>component (#9094)Updated Dependencies
@remix-run/router@1.0.0v6.3.0: react-router@v6.3.0Compare Source
What's Changed
New Contributors
Full Changelog: https://github.com/remix-run/react-router/compare/v6.2.2...v6.3.0
v6.2.2Compare Source
What's Changed
🐛 Bug Fixes
New Contributors
Full Changelog: https://github.com/remix-run/react-router/compare/v6.2.1...v6.2.2
v6.2.1Compare Source
This release updates the internal
historydependency to5.2.0.Full Changelog: https://github.com/remix-run/react-router/compare/v6.2.0...v6.2.1
v6.2.0Compare Source
🐛 Bug fixes
RoutePropselementtype, which should be aReactNode(#8473)useOutletfor top-level routes (#8483)✨ Features
New Contributors
Full Changelog: https://github.com/remix-run/react-router/compare/v6.1.1...v6.2.0
v6.1.1Compare Source
In v6.1.0 we inadvertently shipped a new, undocumented API that will likely introduce bugs (#7586). We have flagged
HistoryRouterasunstable_HistoryRouter, as this API will likely need to change before a new major release.Full Changelog: https://github.com/remix-run/react-router/compare/v6.1.0...v6.1.1
v6.1.0Compare Source
🐛 Bug fixes
✨ Features
<Outlet>can now receive acontextprop. This value is passed to child routes and is accessible via the newuseOutletContexthook. See the API docs for details. (#8461)<NavLink>can now receive a child function for access to its props. (#8164)💅 Enhancements
useMatchandmatchPath. For example, when you calluseMatch("foo/:bar/:baz"), the path is parsed and the return type will bePathMatch<"bar" | "baz">. (#8030)New Contributors
Full Changelog: https://github.com/remix-run/react-router/compare/v6.0.1...v6.1.0
v6.0.2Compare Source
✨ Features
reloadDocumentprop to<Link>. This allows<Link>to function like a normal anchor tag by reloading the document after navigation while maintaining the relativetoresolution.🗒️ Docs
🤝 New Contributors
Full Changelog
v6.0.1Compare Source
🐛 Bug Fixes
<StaticRouter location>value (#8243)<Route>inside<Routes>to help people make the change (#8238)v6.0.0Compare Source
React Router v6 is here!
Please go read our blog post for more information on all the great stuff in v6 including notes about how to upgrade from React Router v5 and Reach Router.
v6.0.0-beta.8Compare Source
Remember last week when we said
Yeah, about that … 😅
We found and squashed a few high-priority bugs that needed to be addressed first. But it's coming very soon, we promise! In the mean time, here's what you'll get from our eight-est and greatest beta release:
🐛 Bug Fixes
useHrefthat resulted in the incorrect resolved value in cases where abasenameis used on the<Router />component (See #8133 and #8142 for details).*path value) are now correctly ranked ahead of layout routes.🗒️ Docs
We've added lots of goodies to our
docsandexamples, and there's a lot more yet to come. Take a look and see if you find something that makes your work a little easier! We think the lazy loading and custom query parsing examples are particularly cool! 🤓v6.0.0-beta.7Compare Source
In this release we made a small but significant change to how
<Link to="..">works. This is going to help out a lot if you were trying to use links in a*route.We have also backed out our blocking/prompt APIs for the stable v6 release. We will revisit this post 6.0 when we have a little more time to get it right.
✨ Features
The major change in this release could also be classified as a bugfix or a breaking change, depending on how you look at it. We essentialy altered the way
<Link to="..">works. See #8086 for the motivation behind this change.You'll probably want to reread the section in the v5 => v6 migration guide about
<Link to>values (it has been updated), but it basically boils down to this: any leading..segment in a<Link to>value traverses "up" one route and builds upon that route's path instead of just removing one URL segment. This feature really completes the story of relative routes and links.We could consider this a bugfix, since this is how it was always intended to work in the first place. Without it, you'd have a difficult time linking predictably in
*routes because your<a href>would be different depending on the number of segments in the current URL.The reason this could also be considered a breaking change is that
..now works slightly differently in<Link to>than it would in<a href>. When you have<a href="..">it operates on the URL pathname, removing one segment of the current URL. However, since many routes really only match a single segment of the URL, there is often no difference between<Link to="..">and<a href="..">.💔 Breaking Changes
useBlocker(),usePrompt(), and<Prompt>for now. We will revisit these post 6.0 when we have more time to get it right. But we don't want it to block (see what I did there) the release of all the other awesome stuff we've got in v6.🛠 Roadmap
We anticipate this will be the last beta release before v6 stable next week. Please give it a shot and let us know how it goes!
👍 Upgrading
If you're thinking about upgrading to v6, I published a few notes this past week that may help you:
<Redirect>elements from any<Switch>es you may have in your v5 app and how you can get better SEO in the process if you're currently relying on client-side redirects.<Route>elements, which won't work in v6.Both of those posts contain steps you can take today in your v5 app without upgrading to v6.
We are also developing a backwards compat lib that should help some of you upgrade from v5 to v6. We'll post more about this when it's ready.
💻 Installing
Development for v6 has switched from
devto themainbranch.If you'd like to test it out, install from npm:
v6.0.0-beta.6Compare Source
No big enhancements in this release, just squashing bugs and writing lots of tests! Also, we are hard at work on cranking out examples for v6. See the end of this post for an update on our roadmap between here and v6 stable.
🧰 Examples
We have begun creating some examples for v6 that we hope will help developers make effective use of all the new features we have. So far, we have examples for the following:
<Outlet>APIuseNavigate()hook, the<Navigate>element, andlocation.stateuseSearchParams()hook<StaticRouter>on the server and uses a<BrowserRouter>withReactDOM.hydrate()on the clientEach example includes a button in the README that allows you to instantly launch a running instance on StackBlitz that you can play with. We hope you enjoy exploring!
🐛 Bugfixes
<NavLink>match only whole URL segments instead of pieces. This means that<NavLink to="/home/users">will still be active at/home/users, but not at/home/users2. See #7523path) never match unless one of their children do. See #8085af7d038<Routes>. This reverses a decision that we made in beta.5 to remove them. See #8073💔 Breaking Changes
*) match only after a/in the URL. This means that<Route path="files*">will always match as if it were<Route path="files/*">. The router will issue a warning if your route path ends with*but not/*🛠 Roadmap
We are very close to a stable release! The last big code changes we need to make are:
<Link to="..">operates on the URL pathname. However, this makes it difficult to link to the parent route when you're in a splat route. See #8086. This will be a breaking change.useBlocker()and<Prompt>in our initial v6 release, with plans to revisit them and possibly add them back at some point in the future. I still need to write up something here that explains our rationale. This will also be a breaking change.<Routes location>prop will be in v6, but it isn't ideal for animation.💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
v6.0.0-beta.5Compare Source
This week's release adds some much-needed polish to a few niche features of the router: splat routes (a route that uses a
*path) and basenames. It also adds arenderMatchesAPI that completes the story for those of you who may have been usingreact-router-configin v4 and v5.🐛 Bugfixes
*in a child route path matches after a slash following its parent route path. This fixes some situations where the*was overly greedy (see #7972)<Link to=".">anduseResolvedPath(".")values are fixed in splat routes. Previously these resolved relative to the parent route's path. They now resolve relative to the path of the route that rendered them.✨ Enhancements
This release makes it easier to work with apps that have multiple entry points. Using the
<Router basename>prop allows React Router to be easily deployed on only a portion of a larger site by using a portion of the URL pathname (the "basename") to transparently prefix all route paths and link navigations.For example, you can deploy one React Router app at the
/inboxURL prefix, and another one at the/adminprefix. These base URLs represent two different entry points into your app, each with its own bundles. The rest of your site, including the root / URL could be rendered by something other than React Router, for example by your server framework of choice.In the bundle for each entry point, simply initialize React Router with the basename of that entry point.
Then define your routes and link paths without using the
/inboxURL prefix in any of them. The entire app will run relative to that prefix.Another improvement in this release is the addition of the
renderMatchesAPI, which is the complement ofmatchRoutes. These APIs are both very low-level and should not normally be needed. But they are sometimes nice to use if you are doing your own data loading using the array ofmatchesthat you get back frommatchRoutes.matchRoutesandrenderMatchesare the equivalent of thereact-router-configpackage we shipped in v4 and v5, just built directly into the router instead of in a separate package.💔 Breaking Changes
<Routes basename>has moved to<Router basename>. This prop is also available on all router variants (<BrowserRouter>,<HashRouter>, etc.).useLocation().pathnameno longer includes the basename, if present.basenameargument was removed fromuseRoutes. This reverts the signature touseRoutes(routes, location), same as it was previous to beta.4.<Routes>do not get the params from their parents. This helps a set of<Routes>to be more portable by decoupling it from the params of its parents and makes it easier to know which params will be returned fromuseParams(). If you were relying on this behavior previously, you'll need to pass along the params manually to the elements rendered by the descendant<Routes>. See this comment for an example of how this is to be done and for a potential workaround if you really need the old behavior.match.pathnamein a splat route now includes the portion of the pathname matched by the*. This makes the*param behave much more like other dynamic:id-style params.<Link>s in splat routes is changed now because the entire pathname that was matched by that route is now different (see previous bullet). Instead of resolving relative to the portion of the pathname before the*, paths resolve relative to the full pathname that was matched by the route.💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
v6.0.0-beta.4Compare Source
Last week we released a lot of nice little bug features, but we did get a little carried away and let a little bug slip through with relative path resolution. Our bad! That nasty lil' guy is squashed in this week's beta. 🐛
And there's more! Let's dive in…
🐛 Bugfixes
✨ Enhancements
Paramstype which is now generic, so you can add your own types if you know what to expect from functions that return query parameters. (#8019)There was quite a bit of discussion in #7335 from people who are using constants to define their route paths. In this style, paths are often written as absolute paths from the root
/URL. These constants are then able to be used both in<Route path>definitions as well as<Link to>values. It usually looks something like this:This style of use is now fully supported in v6. This is great for people who write their apps like this, but it technically could cause some breakage if you were using absolute paths (that start with
/) in nested routes in previous betas. To fix this, simply remove the/from the beginning of any route paths that are meant to be relative. React Router will throw an error if you are using absolute paths that don't match their parent route paths. Hopefully this should help you find them if you are upgrading.If you were using
<Route path="/">to indicate an index route, you can now use the new<Route index>prop to accomplish the same thing. Theindexprop makes it easy to scan a route config to find the index route. It also provides a guarantee that nobody will ever add children to that route.Here's the same route config as the one above, but rewritten with relative paths and the
indexprop:A lot of our work on React Router is about doing the least surprising thing for our users. Allowing absolute paths in nested routes gets us a little closer to that goal!
💔 Breaking Changes
Removed the ability for nested route paths to begin with a
/and not contain the complete path of their parent routes. This was necessary in order to introduce support for absolute paths in nested routes, described in detail aboveRemoved the
createRoutesFromArrayutility function. You can now pass your routes directly touseRoutesormatchRouteswithout passing it throughcreateRoutesFromArrayfirstRemoved the
PartialRouteObjecttype. If you were importing and using this type before, useRouteObjectinstead, which has been updated to make all properties optionalThe
useRoutesAPI has changed slightly. Instead of passing a basename as the second argument, you should instead pass it as a named property in an object:matchPathfunction now returnsmatch.patterninstead ofmatch.path, which is a little more descriptive about what it actually is💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
v6.0.0-beta.3Compare Source
Loads of goodies for you this week, as well as a few breaking changes for all of you eager beavers who are brave enough to use beta software in production! 🦫
(seriously, thank you all for helping us tighten up our APIs and fix nasty bugs)
💔 Breaking Changes!
NavLinkno longer supports theactiveClassNameoractiveStyleprops. Instead, we provide a more powerful API that allows you to pass functions to either theclassNameorstyleprops to conditionally apply values based on the link'sactivestate. While a bit more verbose in some cases, this offers a nicer experience for folks who use utility class-based CSS. (#7194)useRoutesAPI has changed slightly. Instead of passing a basename as the second argument, you should instead pass it as a named property in an object:🐛 Bugfixes
basenameprop onRoutesis treated as case-insensitive (#7997)useNavigatepreviously used the incorrectpathnamewhen called from parent routes when the URL matches one of its children. This fix also applies touseSearchParams(#7880)✨ Enhancements
RoutesanduseRoutesnow allow you to override thelocation, which may be useful when building some modal interfaces and route transition animations. We are working hard to update our docs to include examples for advanced patterns where this might be useful, but in the mean time this also bringsRoutescloser to feature parity with v5'sSwitchvia thelocationprop. (#7117)useClickHandlerandusePressHandlerto make customizingLinksa bit easier. (#7998)Link, be sure to render an actual HTML anchor element, otherwise your app will likely be inaccessible without a significant amount of additional work which, I assure you, you don't want to do!💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
🙏 Credits
Thanks to @andrelandgraf, @dhulme, @fgatti675, @hugmanrique, @MeiKatz, @chaance and @mjackson for your contributions!
v6.0.0-beta.2Compare Source
🐛 Bugfixes
displayNameback to<Link />and<NavLink />components✨ Enhancements
navigatefunction now prepends hash and search strings by default:useParamsnow returns parameters from nested<Route />s when called in a parent<Route />💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
🙏 Credits
Thanks to @liho98, @wojtekmaj, @cravend, @chaance and @mjackson for your contributions!
Enjoy!
v6.0.0-beta.1Compare Source
We're on the road to a stable v6 release!
There are no new features in this release since
beta.0, but a handful of squashed bugs, perf enhancements, and DX improvements for TypeScript users.🐛 Bugfixes
+characters no longer get decoded into spaces, and that little*is just a little less greedy (e.g.,app/*no longer matchesapples/*).Linkandnavigateshould properly respect thebasenamewhen using absolute paths.✨ Enhancements
navigatorinto a separate context object, meaning your components that calluseNavigatewill probably render a little less often. Wowza, much perf!react-router-domandreact-router-nativenow re-exports all types exported fromreact-router💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
🙏 Credits
Thanks to @brookslybrand, @bogdansoare, @chaance and @mjackson for your contributions!
Enjoy!
remix-run/react-router (react-router-dom)
v6.22.3Compare Source
Patch Changes
@remix-run/router@1.15.3react-router@6.22.3v6.22.2Compare Source
Patch Changes
@remix-run/router@1.15.2react-router@6.22.2v6.22.1Compare Source
Patch Changes
react-router@6.22.1@remix-run/router@1.15.1v6.22.0Compare Source
Minor Changes
window__reactRouterVersiontag for CWV Report detection (#11222)Patch Changes
@remix-run/router@1.15.0react-router@6.22.0v6.21.3Compare Source
Patch Changes
NavLinkisPendingwhen abasenameis used (#11195)unstable_prefix fromBlocker/BlockerFunctiontypes (#11187)react-router@6.21.3v6.21.2Compare Source
Patch Changes
useIdfor internal fetcher keys when available (#11166)@remix-run/router@1.14.2react-router@6.21.2v6.21.1Compare Source
Patch Changes
react-router@6.21.1@remix-run/router@1.14.1v6.21.0Compare Source
Minor Changes
Add a new
future.v7_relativeSplatPathflag to implement a breaking bug fix to relative routing when inside a splat route. (#11087)This fix was originally added in #10983 and was later reverted in #11078 because it was determined that a large number of existing applications were relying on the buggy behavior (see #11052)
The Bug
The buggy behavior is that without this flag, the default behavior when resolving relative paths is to ignore any splat (
*) portion of the current route path.The Background
This decision was originally made thinking that it would make the concept of nested different sections of your apps in
<Routes>easier if relative routing would replace the current splat:Any paths like
/dashboard,/dashboard/team,/dashboard/projectswill match theDashboardroute. The dashboard component itself can then render nested<Routes>:Now, all links and route paths are relative to the router above them. This makes code splitting and compartmentalizing your app really easy. You could render the
Dashboardas its own independent app, or embed it into your large app without making any changes to it.The Problem
The problem is that this concept of ignoring part of a path breaks a lot of other assumptions in React Router - namely that
"."always means the current location pathname for that route. When we ignore the splat portion, we start getting invalid paths when using".":We've also introduced an issue that we can no longer move our
DashboardTeamcomponent around our route hierarchy easily - since it behaves differently if we're underneath a non-splat route, such as/dashboard/:widget. Now, our"."links will, properly point to ourself inclusive of the dynamic param value so behavior will break from it's corresponding usage in a/dashboard/*route.Even worse, consider a nested splat route configuration:
Now, a
<Link to=".">and a<Link to="..">inside theDashboardcomponent go to the same place! That is definitely not correct!Another common issue arose in Data Routers (and Remix) where any
<Form>should post to it's own routeactionif you the user doesn't specify a form action:This is just a compounded issue from the above because the default location for a
Formto submit to is itself (".") - and if we ignore the splat portion, that now resolves to the parent route.The Solution
If you are leveraging this behavior, it's recommended to enable the future flag, move your splat to it's own route, and leverage
../for any links to "sibling" pages:This way,
.means "the full current pathname for my route" in all cases (including static, dynamic, and splat routes) and..always means "my parents pathname".Patch Changes
@remix-run/router@1.14.0react-router@6.21.0v6.20.1Compare Source
Patch Changes
useResolvedPathfix for splat routes due to a large number of applications that were relying on the buggy behavior (see #11052 (comment)). We plan to re-introduce this fix behind a future flag in the next minor version. (#11078)react-router@6.20.1@remix-run/router@1.13.1v6.20.0Compare Source
Minor Changes
PathParamtype from the public API (#10719)Patch Changes
react-router@6.20.0@remix-run/router@1.13.0v6.19.0Compare Source
Minor Changes
unstable_flushSyncoption touseNavigate/useSumbit/fetcher.load/fetcher.submitto opt-out ofReact.startTransitionand intoReactDOM.flushSyncfor state updates (#11005)unstable_usePromptto accept aBlockerFunctionin addition to aboolean(#10991)Patch Changes
keyin auseFetcherthat remains mounted wasn't getting picked up (#11009)useFormActionwhich was incorrectly inheriting the?indexquery param from child routeactionsubmissions (#11025)NavLinkactivelogic whentolocation has a trailing slash (#10734)react-router@6.19.0@remix-run/router@1.12.0v6.18.0Compare Source
Minor Changes
Add support for manual fetcher key specification via
useFetcher({ key: string })so you can access the same fetcher instance from different components in your application without prop-drilling (RFC) (#10960)useFetchersso that they can be looked up bykeyAdd
navigate/fetcherKeyparams/props touseSumbit/Formto support kicking off a fetcher submission under the hood with an optionally user-specifiedkey(#10960)useFetcher({ key })to look it up elsewherePatch Changes
RouterProviderthat holds completed fetcher data, in preparation for the upcoming future flag that will change the fetcher persistence/cleanup behavior (#10961)futureprop onBrowserRouter,HashRouterandMemoryRouterso that it accepts aPartial<FutureConfig>instead of requiring all flags to be included. (#10962)@remix-run/router@1.11.0react-router@6.18.0v6.17.0Compare Source
Minor Changes
Add experimental support for the View Transitions API via
document.startViewTransitionto enable CSS animated transitions on SPA navigations in your application. (#10916)The simplest approach to enabling a View Transition in your React Router app is via the new
<Link unstable_viewTransition>prop. This will cause the navigation DOM update to be wrapped indocument.startViewTransitionwhich will enable transitions for the DOM update. Without any additional CSS styles, you'll get a basic cross-fade animation for your page.If you need to apply more fine-grained styles for your animations, you can leverage the
unstable_useViewTransitionStatehook which will tell you when a transition is in progress and you can use that to apply classes or styles:You can also use the
<NavLink unstable_viewTransition>shorthand which will manage the hook usage for you and automatically add atransitioningclass to the<a>during the transition:For an example usage of View Transitions with React Router, check out our fork of the Astro Records demo.
For more information on using the View Transitions API, please refer to the Smooth and simple transitions with the View Transitions API guide from the Google Chrome team.
Please note, that because the
ViewTransitionAPI is a DOM API, we now export a specificRouterProviderfromreact-router-domwith this functionality. If you are importingRouterProviderfromreact-router, then it will not support view transitions. (#10928Patch Changes
ScrollRestorationwhensessionStorageis unavailable (#10848)@remix-run/router@1.10.0react-router@6.17.0v6.16.0Compare Source
Minor Changes
@remix-run/router@1.9.0react-router@6.16.0Patch Changes
v6.15.0Compare Source
Minor Changes
redirectDocument()function which allows users to specify that a redirect from aloader/actionshould trigger a document reload (viawindow.location) instead of attempting to navigate to the redirected location via React Router (#10705)Patch Changes
URLSearchParamsand theuseSearchParamshook. (#10620)useFormAction()for unspecified actions since it cannot be determined on the server and causes hydration issues (#10758)unstable_usePromptto avoid throwing an exception if the prompt is unblocked and a navigation is performed synchronously (#10687, #10718)@remix-run/router@1.8.0react-router@6.15.0v6.14.2Compare Source
Patch Changes
<ScrollRestoration>(#10682)<Form state>prop to populatehistory.stateon submission navigations (#10630)Errorsubclasses such asReferenceError/TypeError(#10633)@remix-run/router@1.7.2react-router@6.14.2v6.14.1Compare Source
Patch Changes
react-router@6.14.1@remix-run/router@1.7.1v6.14.0Compare Source
Minor Changes
Add support for
application/jsonandtext/plainencodings foruseSubmit/fetcher.submit. To reflect these additional types,useNavigation/useFetchernow also containnavigation.json/navigation.textandfetcher.json/fetcher.textwhich include the json/text submission if applicable (#10413)Patch Changes
submitterelement, prefer the built-innew FormData(form, submitter)instead of the previous manual approach in modern browsers (those that support the newsubmitterparameter) (#9865, #10627)type="image"buttonsformdata-submitter-polyfillwindow.history.pushState/replaceStatebefore updating React Router state (instead of after) so thatwindow.locationmatchesuseLocationduring synchronous React 17 rendering (#10448)window.locationand should always referenceuseLocationwhen possible, aswindow.locationwill not be in sync 100% of the time (due topopstateevents, concurrent mode, etc.)tsc --skipLibCheck:falseissues on React 17 (#10622)typescriptto 5.1 (#10581)react-router@6.14.0@remix-run/router@1.7.0v6.13.0Compare Source
Minor Changes
Move
React.startTransitionusage behind a future flag to avoid issues with existing incompatibleSuspenseusages. We recommend folks adopting this flag to be better compatible with React concurrent mode, but if you run into issues you can continue without the use ofstartTransitionuntil v7. Issues usually boils down to creating net-new promises during the render cycle, so if you run into issues you should either lift your promise creation out of the render cycle or put it behind auseMemo. (#10596)Existing behavior will no longer include
React.startTransition:If you wish to enable
React.startTransition, pass the future flag to your component:Patch Changes
React.startTransitionminification bug in production mode (#10588)react-router@6.13.0v6.12.1Compare Source
Patch Changes
React.startTransitionto fix webpack + react 17 compilation error (#10569)react-router@6.12.1v6.12.0Compare Source
Minor Changes
React.startTransitionif it exists (#10438)Patch Changes
DOMException(DataCloneError) when attempting to perform aPUSHnavigation with non-serializable state. (#10427)@remix-run/router@1.6.3react-router@6.12.0v6.11.2Compare Source
Patch Changes
SetURLSearchParamstype (#10444)react-router@6.11.2@remix-run/router@1.6.2v6.11.1Compare Source
Patch Changes
react-router@6.11.1@remix-run/router@1.6.1v6.11.0Compare Source
Minor Changes
basenamesupport inuseFetcher(#10336)basenamethen you will need to remove the manually prependedbasenamefrom yourfetchercalls (fetcher.load('/basename/route') -> fetcher.load('/route'))Patch Changes
Componentinstead ofelementon a route definition (#10287)<Link to="//">and other invalid URL values (#10367)useSyncExternalStoretouseStatefor internal@remix-run/routerrouter state syncing in<RouterProvider>. We found some subtle bugs where router state updates got propagated before other normaluseStateupdates, which could lead to footguns inuseEffectcalls. (#10377, #10409)StaticRouterProvider's internalRoutercomponent (#10401)RouterProvider,useNavigate/useSubmit/fetcher.submitare now stable across location changes, since we can handle relative routing via the@remix-run/routerinstance and get rid of our dependence onuseLocation(). When usingBrowserRouter, these hooks remain unstable across location changes because they still rely onuseLocation(). (#10336)react-router@6.11.0@remix-run/router@1.6.0v6.10.0Compare Source
Minor Changes
Added support for Future Flags in React Router. The first flag being introduced is
future.v7_normalizeFormMethodwhich will normalize the exposeduseNavigation()/useFetcher()formMethodfields as uppercase HTTP methods to align with thefetch()behavior. (#10207)future.v7_normalizeFormMethod === false(default v6 behavior),useNavigation().formMethodis lowercaseuseFetcher().formMethodis lowercasefuture.v7_normalizeFormMethod === true:useNavigation().formMethodis uppercaseuseFetcher().formMethodis uppercasePatch Changes
createStaticHandlerto also check forErrorBoundaryon routes in addition toerrorElement(#10190)@remix-run/router@1.5.0react-router@6.10.0v6.9.0Compare Source
Minor Changes
React Router now supports an alternative way to define your route
elementanderrorElementfields as React Components instead of React Elements. You can instead pass a React Component to the newComponentandErrorBoundaryfields if you choose. There is no functional difference between the two, so use whichever approach you prefer 😀. You shouldn't be defining both, but if you doComponent/ErrorBoundarywill "win". (#10045)Example JSON Syntax
Example JSX Syntax
Introducing Lazy Route Modules! (#10045)
In order to keep your application bundles small and support code-splitting of your routes, we've introduced a new
lazy()route property. This is an async function that resolves the non-route-matching portions of your route definition (loader,action,element/Component,errorElement/ErrorBoundary,shouldRevalidate,handle).Lazy routes are resolved on initial load and during the
loadingorsubmittingphase of a navigation or fetcher call. You cannot lazily define route-matching properties (path,index,children) since we only execute your lazy route functions after we've matched known routes.Your
lazyfunctions will typically return the result of a dynamic import.Then in your lazy route modules, export the properties you want defined for the route:
An example of this in action can be found in the
examples/lazy-loading-router-providerdirectory of the repository.🙌 Huge thanks to @rossipedia for the Initial Proposal and POC Implementation.
Updated dependencies:
react-router@6.9.0@remix-run/router@1.4.0v6.8.2Compare Source
Patch Changes
<Link to>as external if they are outside of the routerbasename(#10135)useBlockerto returnIDLE_BLOCKERduring SSR (#10046)<Link to>urls (#10112)StaticRouterProviderserialized hydration data (#10068)@remix-run/router@1.3.3react-router@6.8.2v6.8.1Compare Source
Patch Changes
Linkcomponent (now also supportsmailto:urls) (#9994)react-router@6.8.1@remix-run/router@1.3.2v6.8.0Compare Source
Minor Changes
Support absolute URLs in
<Link to>. If the URL is for the current origin, it will still do a client-side navigation. If the URL is for a different origin then it will do a fresh document request for the new origin. (#9900)Patch Changes
useSearchParams(#9969)preventScrollReseton<fetcher.Form>(#9963)pagehideinstead ofbeforeunloadfor<ScrollRestoration>. This has better cross-browser support, specifically on Mobile Safari. (#9945)@remix-run/router@1.3.1react-router@6.8.0v6.7.0Compare Source
Minor Changes
unstable_useBlockerhook for blocking navigations within the app's location origin (#9709)unstable_usePrompthook for blocking navigations within the app's location origin (#9932)preventScrollResetprop to<Form>(#9886)Patch Changes
useBeforeUnload(#9709)@remix-run/router@1.3.0react-router@6.7.0v6.6.2Compare Source
Patch Changes
useIdconsistency during SSR (#9805)react-router@6.6.2v6.6.1Compare Source
Patch Changes
@remix-run/router@1.2.1react-router@6.6.1v6.6.0Compare Source
Minor Changes
useBeforeUnload()hook (#9664)unstable_prefix fromcreateStaticHandler/createStaticRouter/StaticRouterProvider(#9738)Patch Changes
Errorobjects fromStaticRouterProvider(#9664)<Form method>anduseSubmitmethod values (#9664)hydrationData(#9664)<button formmethod>form submission overriddes (#9664)@remix-run/router@1.2.0react-router@6.6.0v6.5.0Compare Source
Patch Changes
react-router@6.5.0@remix-run/router@1.1.0v6.4.5Compare Source
Patch Changes
@remix-run/router@1.0.5react-router@6.4.5v6.4.4Compare Source
Patch Changes
NavLinkand descendant<Routes>(#9589, #9647)ErrorResponseinstances when using built-in hydration (#9593)basenamein static data routers (#9591)@remix-run/router@1.0.4react-router@6.4.4v6.4.3Compare Source
Patch Changes
createHashRouter(#9409)indexroutes with apathinuseResolvedPath(#9486)relative=pathprop onNavLink(#9453)NavLinkbehavior for root urls (#9497)@remix-run/router@1.0.3react-router@6.4.3v6.4.2Compare Source
Patch Changes
basenameinuseFormAction(#9352)RouteObject/RoutePropstypes to surface the error in TypeScript. (#9366)react-router@6.4.2@remix-run/router@1.0.2v6.4.1Compare Source
Patch Changes
react-router@6.4.1@remix-run/router@1.0.1v6.4.0Compare Source
Whoa this is a big one!
6.4.0brings all the data loading and mutation APIs over from Remix. Here's a quick high level overview, but it's recommended you go check out the docs, especially the feature overview and the tutorial.New APIs
createMemoryRouter/createBrowserRouter/createHashRouter<RouterProvider>loaderand mutate with a RouteactionerrorElement<Form>componentuseFetcher()deferandAwait<ScrollRestoration>New Features
<Link relative="path">(#9160)Bug Fixes
useLocationreturns the scoped location inside a<Routes location>component (#9094)<Link replace>prop if it is defined (#8779)Updated Dependencies
react-router@6.4.0v6.3.0: react-router@v6.3.0Compare Source
What's Changed
New Contributors
Full Changelog: https://github.com/remix-run/react-router/compare/v6.2.2...v6.3.0
v6.2.2Compare Source
What's Changed
🐛 Bug Fixes
New Contributors
Full Changelog: https://github.com/remix-run/react-router/compare/v6.2.1...v6.2.2
v6.2.1Compare Source
This release updates the internal
historydependency to5.2.0.Full Changelog: https://github.com/remix-run/react-router/compare/v6.2.0...v6.2.1
v6.2.0Compare Source
🐛 Bug fixes
RoutePropselementtype, which should be aReactNode(#8473)useOutletfor top-level routes (#8483)✨ Features
New Contributors
Full Changelog: https://github.com/remix-run/react-router/compare/v6.1.1...v6.2.0
v6.1.1Compare Source
In v6.1.0 we inadvertently shipped a new, undocumented API that will likely introduce bugs (#7586). We have flagged
HistoryRouterasunstable_HistoryRouter, as this API will likely need to change before a new major release.Full Changelog: https://github.com/remix-run/react-router/compare/v6.1.0...v6.1.1
v6.1.0Compare Source
🐛 Bug fixes
✨ Features
<Outlet>can now receive acontextprop. This value is passed to child routes and is accessible via the newuseOutletContexthook. See the API docs for details. (#8461)<NavLink>can now receive a child function for access to its props. (#8164)💅 Enhancements
useMatchandmatchPath. For example, when you calluseMatch("foo/:bar/:baz"), the path is parsed and the return type will bePathMatch<"bar" | "baz">. (#8030)New Contributors
Full Changelog: https://github.com/remix-run/react-router/compare/v6.0.1...v6.1.0
v6.0.2Compare Source
✨ Features
reloadDocumentprop to<Link>. This allows<Link>to function like a normal anchor tag by reloading the document after navigation while maintaining the relativetoresolution.🗒️ Docs
🤝 New Contributors
Full Changelog
v6.0.1Compare Source
🐛 Bug Fixes
<StaticRouter location>value (#8243)<Route>inside<Routes>to help people make the change (#8238)v6.0.0Compare Source
React Router v6 is here!
Please go read our blog post for more information on all the great stuff in v6 including notes about how to upgrade from React Router v5 and Reach Router.
v6.0.0-beta.8Compare Source
Remember last week when we said
Yeah, about that … 😅
We found and squashed a few high-priority bugs that needed to be addressed first. But it's coming very soon, we promise! In the mean time, here's what you'll get from our eight-est and greatest beta release:
🐛 Bug Fixes
useHrefthat resulted in the incorrect resolved value in cases where abasenameis used on the<Router />component (See #8133 and #8142 for details).*path value) are now correctly ranked ahead of layout routes.🗒️ Docs
We've added lots of goodies to our
docsandexamples, and there's a lot more yet to come. Take a look and see if you find something that makes your work a little easier! We think the lazy loading and custom query parsing examples are particularly cool! 🤓v6.0.0-beta.7Compare Source
In this release we made a small but significant change to how
<Link to="..">works. This is going to help out a lot if you were trying to use links in a*route.We have also backed out our blocking/prompt APIs for the stable v6 release. We will revisit this post 6.0 when we have a little more time to get it right.
✨ Features
The major change in this release could also be classified as a bugfix or a breaking change, depending on how you look at it. We essentialy altered the way
<Link to="..">works. See #8086 for the motivation behind this change.You'll probably want to reread the section in the v5 => v6 migration guide about
<Link to>values (it has been updated), but it basically boils down to this: any leading..segment in a<Link to>value traverses "up" one route and builds upon that route's path instead of just removing one URL segment. This feature really completes the story of relative routes and links.We could consider this a bugfix, since this is how it was always intended to work in the first place. Without it, you'd have a difficult time linking predictably in
*routes because your<a href>would be different depending on the number of segments in the current URL.The reason this could also be considered a breaking change is that
..now works slightly differently in<Link to>than it would in<a href>. When you have<a href="..">it operates on the URL pathname, removing one segment of the current URL. However, since many routes really only match a single segment of the URL, there is often no difference between<Link to="..">and<a href="..">.💔 Breaking Changes
useBlocker(),usePrompt(), and<Prompt>for now. We will revisit these post 6.0 when we have more time to get it right. But we don't want it to block (see what I did there) the release of all the other awesome stuff we've got in v6.🛠 Roadmap
We anticipate this will be the last beta release before v6 stable next week. Please give it a shot and let us know how it goes!
👍 Upgrading
If you're thinking about upgrading to v6, I published a few notes this past week that may help you:
<Redirect>elements from any<Switch>es you may have in your v5 app and how you can get better SEO in the process if you're currently relying on client-side redirects.<Route>elements, which won't work in v6.Both of those posts contain steps you can take today in your v5 app without upgrading to v6.
We are also developing a backwards compat lib that should help some of you upgrade from v5 to v6. We'll post more about this when it's ready.
💻 Installing
Development for v6 has switched from
devto themainbranch.If you'd like to test it out, install from npm:
v6.0.0-beta.6Compare Source
No big enhancements in this release, just squashing bugs and writing lots of tests! Also, we are hard at work on cranking out examples for v6. See the end of this post for an update on our roadmap between here and v6 stable.
🧰 Examples
We have begun creating some examples for v6 that we hope will help developers make effective use of all the new features we have. So far, we have examples for the following:
<Outlet>APIuseNavigate()hook, the<Navigate>element, andlocation.stateuseSearchParams()hook<StaticRouter>on the server and uses a<BrowserRouter>withReactDOM.hydrate()on the clientEach example includes a button in the README that allows you to instantly launch a running instance on StackBlitz that you can play with. We hope you enjoy exploring!
🐛 Bugfixes
<NavLink>match only whole URL segments instead of pieces. This means that<NavLink to="/home/users">will still be active at/home/users, but not at/home/users2. See #7523path) never match unless one of their children do. See #8085af7d038<Routes>. This reverses a decision that we made in beta.5 to remove them. See #8073💔 Breaking Changes
*) match only after a/in the URL. This means that<Route path="files*">will always match as if it were<Route path="files/*">. The router will issue a warning if your route path ends with*but not/*🛠 Roadmap
We are very close to a stable release! The last big code changes we need to make are:
<Link to="..">operates on the URL pathname. However, this makes it difficult to link to the parent route when you're in a splat route. See #8086. This will be a breaking change.useBlocker()and<Prompt>in our initial v6 release, with plans to revisit them and possibly add them back at some point in the future. I still need to write up something here that explains our rationale. This will also be a breaking change.<Routes location>prop will be in v6, but it isn't ideal for animation.💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
v6.0.0-beta.5Compare Source
This week's release adds some much-needed polish to a few niche features of the router: splat routes (a route that uses a
*path) and basenames. It also adds arenderMatchesAPI that completes the story for those of you who may have been usingreact-router-configin v4 and v5.🐛 Bugfixes
*in a child route path matches after a slash following its parent route path. This fixes some situations where the*was overly greedy (see #7972)<Link to=".">anduseResolvedPath(".")values are fixed in splat routes. Previously these resolved relative to the parent route's path. They now resolve relative to the path of the route that rendered them.✨ Enhancements
This release makes it easier to work with apps that have multiple entry points. Using the
<Router basename>prop allows React Router to be easily deployed on only a portion of a larger site by using a portion of the URL pathname (the "basename") to transparently prefix all route paths and link navigations.For example, you can deploy one React Router app at the
/inboxURL prefix, and another one at the/adminprefix. These base URLs represent two different entry points into your app, each with its own bundles. The rest of your site, including the root / URL could be rendered by something other than React Router, for example by your server framework of choice.In the bundle for each entry point, simply initialize React Router with the basename of that entry point.
Then define your routes and link paths without using the
/inboxURL prefix in any of them. The entire app will run relative to that prefix.Another improvement in this release is the addition of the
renderMatchesAPI, which is the complement ofmatchRoutes. These APIs are both very low-level and should not normally be needed. But they are sometimes nice to use if you are doing your own data loading using the array ofmatchesthat you get back frommatchRoutes.matchRoutesandrenderMatchesare the equivalent of thereact-router-configpackage we shipped in v4 and v5, just built directly into the router instead of in a separate package.💔 Breaking Changes
<Routes basename>has moved to<Router basename>. This prop is also available on all router variants (<BrowserRouter>,<HashRouter>, etc.).useLocation().pathnameno longer includes the basename, if present.basenameargument was removed fromuseRoutes. This reverts the signature touseRoutes(routes, location), same as it was previous to beta.4.<Routes>do not get the params from their parents. This helps a set of<Routes>to be more portable by decoupling it from the params of its parents and makes it easier to know which params will be returned fromuseParams(). If you were relying on this behavior previously, you'll need to pass along the params manually to the elements rendered by the descendant<Routes>. See this comment for an example of how this is to be done and for a potential workaround if you really need the old behavior.match.pathnamein a splat route now includes the portion of the pathname matched by the*. This makes the*param behave much more like other dynamic:id-style params.<Link>s in splat routes is changed now because the entire pathname that was matched by that route is now different (see previous bullet). Instead of resolving relative to the portion of the pathname before the*, paths resolve relative to the full pathname that was matched by the route.💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
v6.0.0-beta.4Compare Source
Last week we released a lot of nice little bug features, but we did get a little carried away and let a little bug slip through with relative path resolution. Our bad! That nasty lil' guy is squashed in this week's beta. 🐛
And there's more! Let's dive in…
🐛 Bugfixes
✨ Enhancements
Paramstype which is now generic, so you can add your own types if you know what to expect from functions that return query parameters. (#8019)There was quite a bit of discussion in #7335 from people who are using constants to define their route paths. In this style, paths are often written as absolute paths from the root
/URL. These constants are then able to be used both in<Route path>definitions as well as<Link to>values. It usually looks something like this:This style of use is now fully supported in v6. This is great for people who write their apps like this, but it technically could cause some breakage if you were using absolute paths (that start with
/) in nested routes in previous betas. To fix this, simply remove the/from the beginning of any route paths that are meant to be relative. React Router will throw an error if you are using absolute paths that don't match their parent route paths. Hopefully this should help you find them if you are upgrading.If you were using
<Route path="/">to indicate an index route, you can now use the new<Route index>prop to accomplish the same thing. Theindexprop makes it easy to scan a route config to find the index route. It also provides a guarantee that nobody will ever add children to that route.Here's the same route config as the one above, but rewritten with relative paths and the
indexprop:A lot of our work on React Router is about doing the least surprising thing for our users. Allowing absolute paths in nested routes gets us a little closer to that goal!
💔 Breaking Changes
Removed the ability for nested route paths to begin with a
/and not contain the complete path of their parent routes. This was necessary in order to introduce support for absolute paths in nested routes, described in detail aboveRemoved the
createRoutesFromArrayutility function. You can now pass your routes directly touseRoutesormatchRouteswithout passing it throughcreateRoutesFromArrayfirstRemoved the
PartialRouteObjecttype. If you were importing and using this type before, useRouteObjectinstead, which has been updated to make all properties optionalThe
useRoutesAPI has changed slightly. Instead of passing a basename as the second argument, you should instead pass it as a named property in an object:matchPathfunction now returnsmatch.patterninstead ofmatch.path, which is a little more descriptive about what it actually is💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
v6.0.0-beta.3Compare Source
Loads of goodies for you this week, as well as a few breaking changes for all of you eager beavers who are brave enough to use beta software in production! 🦫
(seriously, thank you all for helping us tighten up our APIs and fix nasty bugs)
💔 Breaking Changes!
NavLinkno longer supports theactiveClassNameoractiveStyleprops. Instead, we provide a more powerful API that allows you to pass functions to either theclassNameorstyleprops to conditionally apply values based on the link'sactivestate. While a bit more verbose in some cases, this offers a nicer experience for folks who use utility class-based CSS. (#7194)useRoutesAPI has changed slightly. Instead of passing a basename as the second argument, you should instead pass it as a named property in an object:🐛 Bugfixes
basenameprop onRoutesis treated as case-insensitive (#7997)useNavigatepreviously used the incorrectpathnamewhen called from parent routes when the URL matches one of its children. This fix also applies touseSearchParams(#7880)✨ Enhancements
RoutesanduseRoutesnow allow you to override thelocation, which may be useful when building some modal interfaces and route transition animations. We are working hard to update our docs to include examples for advanced patterns where this might be useful, but in the mean time this also bringsRoutescloser to feature parity with v5'sSwitchvia thelocationprop. (#7117)useClickHandlerandusePressHandlerto make customizingLinksa bit easier. (#7998)Link, be sure to render an actual HTML anchor element, otherwise your app will likely be inaccessible without a significant amount of additional work which, I assure you, you don't want to do!💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
🙏 Credits
Thanks to @andrelandgraf, @dhulme, @fgatti675, @hugmanrique, @MeiKatz, @chaance and @mjackson for your contributions!
v6.0.0-beta.2Compare Source
🐛 Bugfixes
displayNameback to<Link />and<NavLink />components✨ Enhancements
navigatefunction now prepends hash and search strings by default:useParamsnow returns parameters from nested<Route />s when called in a parent<Route />💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
🙏 Credits
Thanks to @liho98, @wojtekmaj, @cravend, @chaance and @mjackson for your contributions!
Enjoy!
v6.0.0-beta.1Compare Source
We're on the road to a stable v6 release!
There are no new features in this release since
beta.0, but a handful of squashed bugs, perf enhancements, and DX improvements for TypeScript users.🐛 Bugfixes
+characters no longer get decoded into spaces, and that little*is just a little less greedy (e.g.,app/*no longer matchesapples/*).Linkandnavigateshould properly respect thebasenamewhen using absolute paths.✨ Enhancements
navigatorinto a separate context object, meaning your components that calluseNavigatewill probably render a little less often. Wowza, much perf!react-router-domandreact-router-nativenow re-exports all types exported fromreact-router💻 Installing
Development for v6 is chugging along on the
devbranch.If you'd like to test it out, install from npm:
🙏 Credits
Thanks to @brookslybrand, @bogdansoare, @chaance and @mjackson for your contributions!
Enjoy!
Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
This PR has been generated by Renovate Bot.
Update react-router monorepo to v6.22.3to fix(deps): update react-router monorepo to v6.22.3dbd1e61d6ftod2ebbd8ee6d2ebbd8ee6to3e99380a07