Learn
Destinations and routes
Define typed route parameters and results, connect them to pages, and decide which routes can be restored from a URL.
Destinations and routes
A Destination is the public request your application makes. A Route Definition is the Flutter-specific adapter that fulfils that request.
Define parameters and result in one type
final class EditProfileDestination extends NavigationDestination<Profile?> {
const EditProfileDestination({required this.userId});
final String userId;
}
This contract guarantees:
- callers must provide
userId; - the route can return
Profile?; - there is no untyped
extravalue to cast inside the page.
Prefer stable identifiers over large mutable objects. The page can load current data through your application layer.
Connect it to a page
final editProfileRoute =
NavigationRouteDefinition<EditProfileDestination, Profile?>(
id: const NavigationRouteId('edit-profile'),
pageBuilder: (context, destination, entry) => EditProfilePage(
userId: destination.userId,
),
uriCodec: CallbackNavigationUriCodec<EditProfileDestination>(
pattern: '/users/:userId/edit',
encoder: (destination) => Uri(
path: '/users/${destination.userId}/edit',
),
decoder: (match) => EditProfileDestination(
userId: match.path('userId'),
),
),
);
pageBuilder receives the exact Destination type. entry contains runtime identity and Scope metadata; it is not a service container.
Restorable versus session-only
The default restorable policy requires a URI codec. Use it for identifiers and values that can be reconstructed after restart.
Use sessionOnly when a Destination contains an object that exists only for the current runtime session:
final previewRoute = NavigationRouteDefinition<PreviewDestination, void>(
id: const NavigationRouteId('preview'),
restorationPolicy: NavigationRestorationPolicy.sessionOnly,
pageBuilder: (context, destination, entry) => PreviewPage(
controller: destination.controller,
),
);
Session-only routes cannot be opened from an external URL and disappear during restoration.
Route, Destination, and Entry are different
NavigationRouteIdidentifies the definition, such asproduct.ProductDestination('a')is one typed request.NavigationEntryIdidentifies one occurrence in the live stack.
If Product is pushed twice, both entries share a Route ID but have different Entry IDs. Use Entry ID when removing one exact occurrence.
When placement must be explicit
If the same feature Module is mounted in two places, provide mountId:
navigation.push<void>(
const CatalogDestination(),
mountId: const NavigationMountId('admin-catalog'),
);
Ark Navigation rejects an ambiguous request instead of choosing a mount by registration order.