Keyboard activation causes full page reload instead of SPA navigation when using custom link with React Aria
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.1k
- Forks
- 1.9k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 143
Description
Which project does this relate to?
Router
Describe the bug
When using a custom link component that wraps TanStack Router's Link with React Aria's Link — via either the
createLink() approach or the internal _asChild prop — keyboard activation (pressing Enter) triggers a full
page reload instead of client-side SPA navigation.
Mouse click works correctly (client-side navigation). The issue is keyboard-only.
Both approaches are affected:
// Approach 1 — createLink()
// https://tanstack.com/router/latest/docs/guide/custom-link
const CustomLink = createLink(AriaLink);
<CustomLink to="/development">Development</CustomLink>
// Approach 2 — _asChild
<RouterLink to="/development" _asChild={AriaLink}>
Development
</RouterLink>
The root cause is likely a mismatch between event models:
- TanStack Router intercepts
onClickand callse.preventDefault()to prevent native navigation - React Aria uses
onPressas its primary activation model and dispatches a synthetic click on keyboard
activation (Enter) - This synthetic click may bypass TSR's
onClickhandler, causing the browser to fall back to nativehref
navigation → full page reload
Your Example Website or App
https://stackblitz.com/edit/vitejs-vite-2xxlupse
Steps to Reproduce the Bug or Issue
- Create a custom link component using React Aria's
Linkwith eithercreateLink()or_asChild - Render two routes (e.g.
/and/development) - Click a link with the mouse → observe client-side navigation ✅
- Focus the same link and press
Enter→ observe full page reload ❌
Expected behavior
Pressing Enter on a custom link should trigger client-side SPA navigation, identical to mouse click behavior.
e.preventDefault() should be called to prevent the browser from following the href natively.
Screenshots or Videos
No response
Platform
- Router Version: 1.168.10
- OS: macOS, Windows, Linux
- Browser: Chrome, Safari, Firefox
- Bundler: Vite
- Bundler Version: 8.0.3
Additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue in the linked StackBlitz example using both the createLink() and _asChild approaches, then inspect the custom-link integration and keyboard activation path. Done means pressing Enter on either custom link performs client-side SPA navigation without a full page reload, matching mouse-click behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100