You should do is move to the route /login (or any other your preferred with login) and set that as initialRoute. And based on that you can modify the onGenerateInitialRoutes property of the app, to make sure that the routes are actually not pushed into Navigator history. That way you override the defaultGenerateInitialRoutes which is pushing those home state on to your Navigator. Check this code snippet from Flutter's site.
https://api.flutter.dev/flutter/widgets/Navigator/defaultGenerateInitialRoutes.html
Will copy it here as well, just in case link not works in future.
defaultGenerateInitialRoutes method List
defaultGenerateInitialRoutes ( NavigatorState navigator, String
initialRouteName ) Turn a route name into a set of Route objects.
This is the default value of onGenerateInitialRoutes, which is used if
initialRoute is not null.
If this string contains any / characters, then the string is split on
those characters and substrings from the start of the string up to
each such character are, in turn, used as routes to push.
For example, if the route /stocks/HOOLI was used as the initialRoute,
then the Navigator would push the following routes on startup: /,
/stocks, /stocks/HOOLI. This enables deep linking while allowing the
application to maintain a predictable route history.
static List<Route<dynamic>> defaultGenerateInitialRoutes(NavigatorState navigator, String initialRouteName) {
final List<Route<dynamic>> result = <Route<dynamic>>[];
if (initialRouteName.startsWith('/') && initialRouteName.length > 1) {
initialRouteName = initialRouteName.substring(1); // strip leading '/'
assert(Navigator.defaultRouteName == '/');
List<String> debugRouteNames;
assert(() {
debugRouteNames = <String>[ Navigator.defaultRouteName ];
return true;
}());
result.add(navigator._routeNamed<dynamic>(Navigator.defaultRouteName, arguments: null, allowNull: true));
final List<String> routeParts = initialRouteName.split('/');
if (initialRouteName.isNotEmpty) {
String routeName = '';
for (final String part in routeParts) {
routeName += '/$part';
assert(() {
debugRouteNames.add(routeName);
return true;
}());
result.add(navigator._routeNamed<dynamic>(routeName, arguments: null, allowNull: true));
}
}
if (result.last == null) {
assert(() {
FlutterError.reportError(
FlutterErrorDetails(
exception:
'Could not navigate to initial route.\n'
'The requested route name was: "/$initialRouteName"\n'
'There was no corresponding route in the app, and therefore the initial route specified will be '
'ignored and "${Navigator.defaultRouteName}" will be used instead.'
),
);
return true;
}());
result.clear();
}
} else if (initialRouteName != Navigator.defaultRouteName) {
// If initialRouteName wasn't '/', then we try to get it with allowNull:true, so that if that fails,
// we fall back to '/' (without allowNull:true, see below).
result.add(navigator._routeNamed<dynamic>(initialRouteName, arguments: null, allowNull: true));
}
// Null route might be a result of gap in initialRouteName
//
// For example, routes = ['A', 'A/B/C'], and initialRouteName = 'A/B/C'
// This should result in result = ['A', null,'A/B/C'] where 'A/B' produces
// the null. In this case, we want to filter out the null and return
// result = ['A', 'A/B/C'].
result.removeWhere((Route<dynamic> route) => route == null);
if (result.isEmpty)
result.add(navigator._routeNamed<dynamic>(Navigator.defaultRouteName, arguments: null));
return result;
}