Recipes

Authentication, authorization, and unsaved changes

Apply the right policy contract for login redirection, permission denial, leave protection, and session refresh.

v1.1.0Intermediate

Authentication, authorization, and unsaved changes

Signed out: open Login instead

Implement NavigationRedirect. Return LoginDestination; do not push Login from inside the policy.

dart
if (!session.isSignedIn && context.target.destination is AccountDestination) {
  return const NavigationTarget<Object?>(destination: LoginDestination());
}
return null;

Signed in but forbidden: keep the current screen

Implement an enter Guard:

dart
if (context.phase == NavigationGuardPhase.enter && !permissions.canManageUsers) {
  return const NavigationGuardDenied(reason: AccessReason.missingPermission);
}
return const NavigationGuardAllowed();

The caller receives NavigationRejected and decides how to present the denial.

Unsaved editor: reject leaving

dart
if (context.phase == NavigationGuardPhase.leave && editor.hasUnsavedChanges) {
  return const NavigationGuardDenied(reason: EditorReason.unsavedChanges);
}

Show confirmation outside the Guard. After the user confirms, mark the editor safe and repeat the requested operation.

User signs out while Account is visible

Pass ListenableNavigationPolicyRefresh(sessionState) to NavigationSession. Calling notifyListeners() reconciles the visible route. You do not need to inject navigation into every private page.

Expected denials are not failures. Send only thrown policy errors to NavigationFailureSink.