Learn

Destinations and routes

Define typed route parameters and results, connect them to pages, and decide which routes can be restored from a URL.

v1.1.0Beginner

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

dart
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 extra value 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

dart
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:

dart
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

  • NavigationRouteId identifies the definition, such as product.
  • ProductDestination('a') is one typed request.
  • NavigationEntryId identifies 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:

dart
navigation.push<void>(
  const CatalogDestination(),
  mountId: const NavigationMountId('admin-catalog'),
);

Ark Navigation rejects an ambiguous request instead of choosing a mount by registration order.