Can I listen to unload of a page and conditionally prevent navigation?
I can't find it in the docs, I'd like to know if router currently supports something to show the "you have unsaved data" popup when navigating away from a page (either from navigation or closing the browser window)
9 Replies
other-emerald•16mo ago
you could use navigation blocking:
https://tanstack.com/router/v1/docs/framework/react/guide/navigation-blocking
Navigation Blocking | TanStack Router React Docs
Navigation blocking is a way to prevent navigation from happening. This is typical if a user attempts to navigate while they:
Have unsaved changes
flat-fuchsiaOP•16mo ago
Exactly what I was looking for, thank you!
Then a feedback on the search: it wasn't finding it 😄


continuing-cyan•16mo ago
Is there a way to display custom UI while blocking navigation? Ideally I'd like to show a custom confirmation dialog, and then proceed with navigation when the confirm button is clicked. It looks like there's no way currently to manually remove the block
flat-fuchsiaOP•16mo ago
If the navigation is performed by the router, you're in full control and can show custom UI (e.g. a user clicks on a button in your app) but if the navigation is triggered outside (e.g. closing the browser tab) then it will take the browser's default
continuing-cyan•16mo ago
I managed to make it work with an ugly workaround, but I don't think what I need is achievable with the current implementation.
useBlocker
here wants a function that returns a boolean, however i'm using that function to display a dialog prompting the user to either stay or navigate.
Now, there's no way to tell the router to keep navigating from the dialog itself, when used this way:
React-router exports a function from the hook that can resume the navigation, and I think that's the key missing here for this pattern.flat-fuchsiaOP•16mo ago
I haven't tried it yet here so maybe I'm wrong, but I see the first parameter of
useBlocker
is type type BlockerFn = () => Promise<ShouldAllowNavigation> | ShouldAllowNavigation;
I assume you can await a promise there and resolve it only when the user clicks confirm/cancel in your custom UI.
That's an interesting topic, I think I'll make a demo on thatcontinuing-cyan•16mo ago
Yeah, this makes sense. However, it'd make more sense if the router exposed a way to do this directly, instead of me having to create a new hook.
This is loosely based off the useBlocker implementation https://gist.github.com/freshgiammi/f1f941739ecd62c0037d8a6003eff226 but seems to be working correctly for now, and I can manually handle the promise in a more ergonomic way.
flat-fuchsiaOP•16mo ago
Absolutely, would be much better if this was natively supported in the library. Maybe it's worth creating an issue 😄
(btw you're from Pesaro? I'm from Fano, how tiny the world is 😂)
continuing-cyan•16mo ago
haha yeah, what a small world 😆