Flutter 3.41 is live! Check out theFlutter 3.41 blog post!
Navigator's page APIs breaking change
Replace Navigator's 'onPopPage' property with the 'onDidRemovePage' property.
These breaking change docs are accurate, as of the release under which they are published. Over time, the workarounds described here might become inaccurate. We don't, in general, keep these breaking change docs up to date as of each release.
Thebreaking change index file lists the docs created for each release.
Summary
# TheNavigator page APIs are refactored so that they can integrate with Flutter's other pop mechanisms.
Context
# TheonPopPage property was added for cleaning up pages after a page is about to be popped. To veto pop, you'd returnfalse in the callback. This did not work well with other popping mechanisms in the framework, such asPopScope and iOS back gestures.
To integrate the framework's pop mechanisms together, the page APIs needed to be refactored.
Description of change
# TheonDidRemovePage property replaces theonPopPage property. You can no longer veto a pop in theonDidRemovePage property. Instead, you are only responsible for updating thepages.
The veto mechanism is now managed with thePage.canPop andPage.onPopInvoked properties. These function similar to how you use thePopScope widget.
Migration guide
#Code before migration:
import'package:flutter/material.dart';finalMaterialPage<void>page1=MaterialPage<void>(child:Placeholder());finalMaterialPage<void>page2=MaterialPage<void>(child:Placeholder());finalMaterialPage<void>page3=MaterialPage<void>(child:Placeholder());voidmain(){finalList<Page<void>>pages=<Page<void>>[page1,page2,page3];runApp(MaterialApp(home:Navigator(pages:pages,onPopPage:(Route<Object?>route,Object?result){if(route.settings==page2){returnfalse;}if(route.didPop){pages.remove(route.settings);returntrue;}returnfalse;},),),);}Code after migration:
import'package:flutter/material.dart';finalMaterialPage<void>page1=MaterialPage<void>(child:Placeholder());finalMaterialPage<void>page2=MaterialPage<void>(canPop:false,child:Placeholder());finalMaterialPage<void>page3=MaterialPage<void>(child:Placeholder());voidmain(){finalList<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.38.6. Page last updated on 2025-10-28.View source orreport an issue.