Skip to content

Add Vue Router-like Navigation Guards to Prevent Navigation #3407

@rongxianyu

Description

@rongxianyu

I'm working with Getx for Flutter navigation and I'm looking for a way to prevent navigation similar to
how Vue Router handles it with navigation guards.

Current Challenge:

In Vue Router, we can easily prevent navigation using navigation guards by returning false or
redirecting:

// Vue Router example
beforeRouteLeave(to, from, next) {
  if (hasUnsavedChanges()) {
    const answer = window.confirm('Do you really want to leave? You have unsaved changes!')
    if (answer) {
      next()
    } else {
      next(false)
    }
  } else {
    next()
  }
}

However, in Getx, preventing navigation without causing route stack issues is challenging. When using
middleware methods like redirect or onPageCalled, returning null or trying to redirect can cause
unexpected behavior.

What I'm Trying to Achieve:

I want to implement permission checks before navigating to certain routes. If the user doesn't have
permission, I want to:

  1. Show a toast message
  2. Prevent navigation to the target page
  3. Not create route stack accumulation issues

Current Workaround:

Currently, I'm handling this in the controller's onInit method:

@override
void onInit() {
  super.onInit();
  // Check permissions
  if (!hasPermission()) {
    ToastMan.show("You don't have permission to access this content");
    Future.microtask(() {
      Get.offAllNamed('/home');
    });
    return;
  }
  // Continue with normal initialization
}

This works but requires adding code to every controller that needs permission checking.

Proposed Solution:

It would be great to have a navigation guard system similar to Vue Router that allows:

  1. Define guards that can prevent navigation
  2. Handle permission checks cleanly in one place
  3. Show user feedback without route stack issues
  4. Return false or similar to prevent navigation

Possible Implementation:

Maybe something like this:

class PermissionGuard extends GetMiddleware {
  @override
  Future<bool> canActivate(String route) async {
    // Check permissions
    if (!await checkPermissions()) {
      ToastMan.show("You don't have permission to access this content");
      return false; // Prevent navigation
    }
    return true; // Allow navigation
  }
}

Is there currently a recommended way to achieve this in Getx? If not, would this be a feature worth
considering?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions