Navigator's page APIs breaking change
Summary
#
                  The Navigator
                   page APIs are refactored so that
                  they can integrate with Flutter's other pop mechanisms.
                
Context
#
                  The onPopPage property was added for cleaning up pages after
                  a page is about to be popped.
                  To veto pop, you'd return false in the callback.
                  This did not work well with other popping mechanisms in the framework,
                  such as PopScope
                   and iOS back gestures.
                
To integrate the framework's pop mechanisms together, the page APIs needed to be refactored.
Description of change
#
                  The onDidRemovePage property replaces the onPopPage property.
                  You can no longer veto a pop in the onDidRemovePage property.
                  Instead, you are only responsible for updating the pages.
                
                  The veto mechanism is now managed with the
                  Page.canPop and Page.onPopInvoked properties.
                  These function similar to how you use the PopScope widget.
                
Migration guide
#Code before migration:
import 'package:flutter/material.dart';
final MaterialPage<void> page1 = MaterialPage<void>(child: Placeholder());
final MaterialPage<void> page2 = MaterialPage<void>(child: Placeholder());
final MaterialPage<void> page3 = MaterialPage<void>(child: Placeholder());
void main() {
  final List<Page<void>> pages = <Page<void>>[page1, page2, page3];
  runApp(
    MaterialApp(
      home: Navigator(
        pages: pages,
        onPopPage: (Route<Object?> route, Object? result) {
          if (route.settings == page2) {
            return false;
          }
          if (route.didPop) {
            pages.remove(route.settings);
            return true;
          }
          return false;
        },
      ),
    ),
  );
}
                    
                    
                    
                  Code after migration:
import 'package:flutter/material.dart';
final MaterialPage<void> page1 = MaterialPage<void>(child: Placeholder());
final MaterialPage<void> page2 = MaterialPage<void>(canPop: false, child: Placeholder());
final MaterialPage<void> page3 = MaterialPage<void>(child: Placeholder());
void main() {
  final List<Page<void>> pages = <Page<void>>[page1, page2, page3];
  runApp(
    MaterialApp(
      home: Navigator(
        pages: pages,
        onDidRemovePage: (Page<Object?> page) {
          pages.remove(page);
        },
      ),
    ),
  );
}
                    
                    
                    
                  Timeline
#
                  Landed in version: 3.22.0-32.0.pre
                  In stable release: 3.24.0
                
References
#API documentation:
Relevant issue:
Relevant PR:
Unless stated otherwise, the documentation on this site reflects Flutter 3.35.5. Page last updated on 2025-10-28. View source or report an issue.