Learn
Redirects, Guards, and refresh
Keep target selection, transition permission, and policy-state refresh as separate contracts.
Redirects, Guards, and refresh
A Redirect answers “which typed Target should be used instead?” A Guard answers “may this transition proceed?” Mixing them creates policies that mutate the Controller while it is already resolving a request.
Policies can live at Graph, Module, Mount, or Route Definition level. Redirects run before Guards. Guards run in leave and enter phases, so unsaved-edit protection is independent from destination access control.
final class EditorGuard implements NavigationGuard {
const EditorGuard(this.editor);
final EditorState editor;
@override
NavigationGuardDecision evaluate(NavigationPolicyContext context) {
if (context.phase == NavigationGuardPhase.leave && editor.hasDraft) {
return const NavigationGuardDenied(reason: UnsavedDraft());
}
return const NavigationGuardAllowed();
}
}
Denial reasons are application-owned values, so they can be enums or sealed types. Authentication and feature flags may change while a route is visible; a NavigationPolicyRefresh signal asks the Session to reconcile the current Destination without making every feature issue manual navigation.