Navigation blocking is a way to prevent navigation from happening. This is typical if a user attempts to navigate while they:
In these situations, a prompt or custom UI should be shown to the user to confirm they want to navigate away.
Navigation blocking adds one or more layers of "blockers" to the entire underlying history API. If any blockers are present, navigation will be paused via one of the following ways:
The back button is a special case. When the user clicks the back button, we cannot intercept or control the browser's behavior in a reliable way, and there is no official way to block it that works across all browsers equally. If you encounter a situation where you need to block the back button, it's recommended to rethink your UI/UX to avoid the back button being destructive to any unsaved user data. Saving data to session storage and restoring it if the user returns to the page is a safe and reliable pattern.
There are 2 ways to use navigation blocking:
Let's imagine we want to prevent navigation if a form is dirty. We can do this by using the useBlocker hook:
import { useBlocker } from '@tanstack/react-router'
function MyComponent() {
const [formIsDirty, setFormIsDirty] = useState(false)
useBlocker(
() => window.confirm('Are you sure you want to leave?'),
formIsDirty,
)
// ...
}
import { useBlocker } from '@tanstack/react-router'
function MyComponent() {
const [formIsDirty, setFormIsDirty] = useState(false)
useBlocker(
() => window.confirm('Are you sure you want to leave?'),
formIsDirty,
)
// ...
}
The useBlocker hook takes 2 arguments:
In addition to logical/hook based blocking, can use the Block component to achieve similar results:
import { Block } from '@tanstack/react-router'
function MyComponent() {
const [formIsDirty, setFormIsDirty] = useState(false)
return (
<Block
blocker={() => window.confirm('Are you sure you want to leave?')}
condition={formIsDirty}
/>
)
// OR
return (
<Block
blocker={() => window.confirm('Are you sure you want to leave?')}
condition={formIsDirty}
>
{/* ... */}
</Block>
)
}
import { Block } from '@tanstack/react-router'
function MyComponent() {
const [formIsDirty, setFormIsDirty] = useState(false)
return (
<Block
blocker={() => window.confirm('Are you sure you want to leave?')}
condition={formIsDirty}
/>
)
// OR
return (
<Block
blocker={() => window.confirm('Are you sure you want to leave?')}
condition={formIsDirty}
>
{/* ... */}
</Block>
)
}
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.