Skip to content
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

Infinite redirects when throwing a redirect with to: '.' #2418

Open
mirague opened this issue Sep 26, 2024 · 2 comments
Open

Infinite redirects when throwing a redirect with to: '.' #2418

mirague opened this issue Sep 26, 2024 · 2 comments

Comments

@mirague
Copy link

mirague commented Sep 26, 2024

Which project does this relate to?

Router

Describe the bug

We used to be able to throw a redirect to update the route params, like so:

// This was both type-safe and working before a few versions ago, now it's still working but _not_ type-safe:
throw redirect({ 
  from: Route.fullPath,
  params: (params) => ({ ...params, id: newId }),
})

This actually still works at runtime but no longer type checks since a few TSR versions back, we're expected to pass the to: '.' to get loose types:

// TS is happy with this, but you'll be in a world of hurt trying to load this page... 🥶
throw redirect({ 
  from: Route.fullPath,
  to: '.',
  params: (params) => ({ ...params, id: newId }),
})

However, throwing a redirect with a to of '.' and updating just a route param causes an infinite redirect loop, causing the browser tab to freeze to a halt.

Known workarounds for this is:

  • Omitting to to get the proper runtime behaviour and using // @ts-expect-error to silence the typescript errors you'll get when trying to set params, search, etc.; OR
  • Providing a full path to to - this is however not always possible when the redirect is thrown in a generic guard/helper function where the current fullPath is not available
// This works, but we won't always have the `fullPath` available, 
// such as in re-used guard/helper functions. For this I expect the `to: '.'` to work
throw redirect({ 
  from: Route.fullPath,
  to: Route.fullPath,
  params: (params) => ({ ...params, id: newId }),
})

Your Example Website or App

https://stackblitz.com/edit/tanstack-router-uyaeym?file=src%2Froutes%2Fusers.%24id.tsx

Steps to Reproduce the Bug or Issue

  1. Go to the page
  2. Press [Go to Logged in User]
  3. Your browser tab is now stuck in an infinite redirect loop

Expected behavior

I expect to be able to throw a redirect to only update the route params. According to the docs we can make the type checks happy by passing to: '.', but this affects the runtime behaviour.

Screenshots or Videos

No response

Platform

macOS, Arc 1.61

Additional context

No response

@schiller-manuel
Copy link
Contributor

the infinite loop is definitely a bug, we'll look into it.
however, based on your descriptiont I would expect that you are only throwing such a redirect using your helper function if the route /users/$id is matched.
So I would set from: '/users/$id' in that helper.

@mirague
Copy link
Author

mirague commented Sep 26, 2024

the infinite loop is definitely a bug, we'll look into it. however, based on your descriptiont I would expect that you are only throwing such a redirect using your helper function if the route /users/$id is matched. So I would set from: '/users/$id' in that helper.

You are right that my example is a bit skewed, I wanted to keep the repro as simple as possible. In the blitzstack you can easily omit the to: '.' and it will work as expected, but that doesn't carry over very well when moving the throw redirect to a generic guard/helper where the from isn't necessarily known, or at best a string type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants