-
Notifications
You must be signed in to change notification settings - Fork 1.3k
better support for Tanstack Router and React Router #7695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
) { | ||
e.preventDefault(); | ||
router.open(e.currentTarget, e, props.href, props.routerOptions); | ||
router.open(e.currentTarget, e, routerLinkProps.href, props.routerOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
routerLinkProps.href is the useHref value, so that relative links are computed correctly. For instance if you are under /blogs in React Router, useHref will compute "/blogs/1" if href="1"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative might be to call it with e.currentTarget.href
The test failures make sense broadly in that its not expecting to use the full path from useHref for navigation.
would be the fix |
@devongovett i think you wrote the related code originally? |
Thanks for the PR, you'll need to sign the CLA https://react-spectrum.adobe.com/contribute.html#contributor-license-agreement Thanks again! |
That's not a problem, the key question is if the updated behaviour is correct or is the current behaviour "as designed" or something. Also how to potentially handle host based links like https://example.com which are quasi-broken even now afaict. |
1853f2e
to
50c495a
Compare
Another alternative would be to add an isExternal flag on the Link component |
This is a breaking change. Shouldn't the router be handling this in the |
Great question:
works fine, I'm not sure why it fails with react-aria. |
I think it might depend on where the You could fix this by calling |
Yes, I think this is the core of the issue.
This does work, but seems awkward; will investigate some alternatives. |
Some findings:
One thought is to separate router links and non-router links in React Aria. |
6eacd58
to
50c495a
Compare
So the Tanstack Link component does actually look for "external"
The buildLocation (https://tanstack.com/router/latest/docs/framework/react/api/router/RouterType#buildlocation-method) router function in Tanstack Router however needs more than just "to" in order to navigate (ie params for Dynamic links - https://tanstack.com/router/latest/docs/framework/react/guide/navigation#dynamic-links )
this would roughly be in Typescript (note the change to Omit):
but also requires router.useHref in React Aria to pass the routerOptions into useHref as well (not just the original href as per Testing link: https://stackblitz.com/edit/github-e3kdjjca |
9a95f7b
to
6568271
Compare
@@ -18,7 +18,7 @@ import React, {createContext, DOMAttributes, ReactNode, useContext, useMemo} fro | |||
interface Router { | |||
isNative: boolean, | |||
open: (target: Element, modifiers: Modifiers, href: Href, routerOptions: RouterOptions | undefined) => void, | |||
useHref: (href: Href) => string | |||
useHref: (href: Href, routerOptions: RouterOptions | undefined) => string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an attempt to get the rest of the options through to useHref so that dynamic links work in Tanstack Router - https://tanstack.com/router/latest/docs/framework/react/guide/navigation#dynamic-links
} | ||
} | ||
|
||
declare module '@adobe/react-spectrum' { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The typing of this is not fully correct - build the buildLocation and navigate options do overlap quite a bit. Also this module extension breaks the types in Link.stories.tsx because its global - however this is useful to temporarily check type safety.
|
||
declare module '@adobe/react-spectrum' { | ||
interface RouterConfig { | ||
href: ValidateNavigateOptions<RegisteredRouter, unknown>['to'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://tanstack.com/router/latest/docs/framework/react/guide/type-utilities#type-checking-navigate-options-with-validatenavigateoptions - the problem is that I don't think we can properly do the generics here and make sure that href causes type safety for things like params but @schiller-manuel will know better than me.
return ( | ||
<RouterProvider | ||
navigate={(to, options) => router.navigate({to, ...options})} | ||
useHref={(to, options) => router.buildLocation({to, ...options}).href}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the change so that $dynamic gets replaced by React Aria.
@devongovett updated approach, and possibly @schiller-manuel can help |
Next step might be to test Tabs or other components that support hrefs? |
Closes #5476 (comment)
This make require a lot of setup for testing, but generally speaking relative links in routers don't work because the useHref'ed value is not used for navigation.
Originally investigated in heroui-inc/heroui
✅ Pull Request Checklist:
📝 Test Instructions:
https://stackblitz.com/edit/wfdcu9f2-5zvxtaag?file=App.jsx has a comparison of the React Router link and RA link behavior for the relative link. Go to
/blogs
in the previewIt is also worth noting that the http:// link href is wrong as well, perhaps the href return value in linkProps should also be guarded with shouldClientNavigate somehow
🧢 Your Project:
https://www.rhino-project.org/ , https://www.heroui.com/ (I'm not affiliated with them, but they are a user of this lib where this first showed up)