router icon indicating copy to clipboard operation
router copied to clipboard

`onBeforeNavigate` not invoked after `redirect` within `beforeLoad` method was invoked

Open JulianAnthes opened this issue 9 months ago • 4 comments

Which project does this relate to?

Router

Describe the bug

When using throw redirect() within a beforeLoad function, subsequent router.subscribe("onBeforeNavigate") events may fail to trigger, causing potential data loss for components that rely on this event for cleanup or persistence operations.

Your Example Website or App

https://github.com/dschu-lab/tanstack-router-onbeforeload-redirect-issue

Steps to Reproduce the Bug or Issue

  • Start with an unauthenticated state
  • Authenticate user (which triggers a redirect() in beforeLoad)
  • Navigate to a page with onBeforeNavigate subscriptions
  • Attempt to navigate away from this page
  • Expected onBeforeNavigate event is not triggered

Subscription to the event is implemented at: https://github.com/dschu-lab/tanstack-router-onbeforeload-redirect-issue/blob/2eb4bd98e7be565983eb7bac8c889859e51da8f3/src/components/PersistForm/PersistForm.tsx#L44-L51

Expected behavior

The onBeforeNavigate event should consistently trigger regardless of whether a redirect() was previously thrown in a beforeLoad or loader function.

Screenshots or Videos

https://github.com/user-attachments/assets/b470b3bc-e17b-4cf3-9861-64d0c0038301

Platform

  • OS: macOS 15.3.2
  • Browser: Chrome
  • Version: 134.0

Additional context

No response

JulianAnthes avatar Apr 02 '25 15:04 JulianAnthes

looks like the redirect state is never reset and thus the event is not emitted anymore https://github.com/TanStack/router/blob/f8015e7629307499d4d6245077ad84145b6064a7/packages/router-core/src/router.ts#L2017C16-L2017C35

schiller-manuel avatar Apr 02 '25 20:04 schiller-manuel

looks like the redirect state is never reset and thus the event is not emitted anymore https://github.com/TanStack/router/blob/f8015e7629307499d4d6245077ad84145b6064a7/packages/router-core/src/router.ts#L2017C16-L2017C35

Thank you for confirming this observation by finding the possible root cause. 🙏

For now we'll set reloadDocument: true when using redirect() within beforeLoad in our SPA as a workaround to bypass this issue.

I would like to submit a fix for this myself, but could not figure out when the redirect state is set and when exactly it should be cleared again. 🙈

JulianAnthes avatar Apr 04 '25 08:04 JulianAnthes

Same problem 😢

wtlin1228 avatar Dec 10 '25 08:12 wtlin1228

Switching to this works for me:

router.subscribe("onBeforeLoad", (...args) => {
  // ...
});

Since the onBeforeLoad will be emitted right after onBeforeNavigate, and onBeforeLoad will not check the this.state.redirect .

ref: https://github.com/TanStack/router/blob/main/packages/router-core/src/router.ts#L2113-L2129

wtlin1228 avatar Dec 11 '25 00:12 wtlin1228