What are Navigation Guards?

Navigation guards allow you to prevent or control navigation based on conditions. This is essential for warning users about unsaved changes, checking authentication, or validating state before leaving a page.

Basic Usage

The navigation guard system provides three main APIs:

  • registerBeforeLeave(handler) - Register a guard function
  • unregisterBeforeLeave(handler) - Remove a guard function
  • NavigationCancelledError - Throw to cancel navigation

Simple Example

Basic navigation guard
 

PageWrapper Pattern (Recommended)

Create a reusable wrapper component to simplify guard registration across your application.

1. Create PageWrapper Component

PageWrapper.svelte
 

2. Use in Your Pages

Using PageWrapper
 

Navigation Context

The beforeLeave handler receives a context object with information about the navigation:

Navigation context
 

Helper Functions

The router provides helper functions for common guard scenarios:

createDirtyCheckGuard

Simplifies creating guards for unsaved changes:

Using createDirtyCheckGuard
 

Browser Navigation & Page Close

Guards can also protect against browser back/forward buttons and page close events by adding an isDirty property to your guard function:

Browser navigation protection
 
Note: The isDirty property only controls the browser's beforeunload event. For router navigation, the main guard function is still called.

Multiple Guards

You can register multiple guards on the same page. All guards must allow navigation for it to proceed:

Multiple guards
 

Async Guards

Guard functions can be asynchronous, allowing you to make API calls or perform complex validation:

Async guard
 

Conditional Guards

You can conditionally apply guards based on the destination or other factors:

Conditional guard
 

Practical Examples

Form with Auto-Save

Auto-save on navigate
 

Multi-Step Form

Multi-step form guard
 

Best Practices

Always Unregister Guards

Make sure to unregister guards in onDestroy to prevent memory leaks and unexpected behavior when the component unmounts.

Use untrack() in $effect

If registering guards in a $effect, wrap the registration in untrack() to prevent infinite loops from reactive dependencies.

Using untrack() in effects
 
Provide Clear Messages

Always explain to users why navigation is being blocked and what they need to do. Generic "Are you sure?" messages provide poor UX.

Try It Live

See navigation guards in action with our interactive demo: