RouteRestorable<T extends RouteTarget> mixin
A mixin that enables custom state restoration for routes that cannot be fully represented by a URI.
What This Mixin Does
RouteRestorable extends RouteTarget to provide explicit control over how a route is serialized to and deserialized from restoration data. While RouteUnique routes can only be saved as URI strings, RouteRestorable routes can preserve arbitrary complex state through custom serialization logic. This is essential for routes that carry rich data objects, computed state, or information that doesn't belong in a URL.
Where to Use This Mixin
Apply this mixin to any route class that needs to preserve state beyond what can be encoded in a URI. This is particularly common for:
- Detail pages with complex loaded data (avoiding refetching on restore)
- Routes with form state or user input that's not yet submitted
- Routes with computed or derived state that's expensive to recreate
- Routes with objects from your domain model (products, users, documents, etc.)
When Restoration Happens
Serialization (serialize is called): Whenever the coordinator's state changes and Flutter needs to save navigation state to the restoration bucket. This happens automatically in the background, typically when the app goes to the background, the user switches to another app, or the system needs to free memory.
Deserialization (deserialize is called): During app launch when Flutter detects existing restoration data. This happens when the system restores your app after terminating it, when the user force-quits and relaunches the app (on some platforms), or during development when hot restart occurs with restoration enabled.
How to Implement Custom Restoration
Complete implementation example combining all required pieces:
// 1. Define your route with RouteRestorable
class BookDetailRoute extends AppRoute with RouteRestorable<BookDetailRoute> {
BookDetailRoute({required this.book});
final Book book; // Complex object that can't be in URL
@override
RestorationStrategy get strategy => RestorationStrategy.converter;
@override
RestorableConverter<BookDetailRoute> get converter => const BookDetailConverter();
@override
String get restorationId => 'book_${book.id}';
@override
Uri toUri() => Uri.parse('/books/${book.id}');
}
// 2. Implement the converter
class BookDetailConverter extends RestorableConverter<BookDetailRoute> {
const BookDetailConverter();
@override
String get key => 'book_detail';
@override
Map<String, dynamic> serialize(BookDetailRoute route) => {
'id': route.book.id,
'title': route.book.title,
'author': route.book.author,
};
@override
BookDetailRoute deserialize(Map<String, dynamic> data) => BookDetailRoute(
book: Book(
id: data['id'],
title: data['title'],
author: data['author'],
),
);
}
// 3. Register in your coordinator
class AppCoordinator extends Coordinator<AppRoute> {
@override
void init() {
super.init();
defineRestorableConverter('book_detail', BookDetailConverter.new);
}
}
Important Considerations
Converter keys must be globally unique and stable: Never change a converter's key in production as it will break restoration for existing users. Prefix keys with your app or package name to avoid collisions.
Serialize efficiently: Only serialize the minimum data needed to reconstruct the route. Large serialized data slows down app startup during restoration.
Handle missing data gracefully: Your deserialize method should handle cases where data might be missing or invalid from older app versions. Provide sensible defaults or fail gracefully.
See also:
- RestorableConverter for implementing the serialization logic
- RestorationStrategy for understanding the available strategies
- CoordinatorRestorable for the overall restoration orchestration
- Superclass constraints
Properties
-
converter
→ RestorableConverter<
T> -
The converter to use when restorationStrategy is RestorationStrategy.converter.
no setter
- hashCode → int
-
The hash code for this object.
no setterinherited
- isPopByPath ↔ bool
-
Whether the pop was initiated by the path mechanism.
getter/setter pairinherited
-
onResult
→ Completer<
Object?> -
no setterinherited
-
props
→ List<
Object?> -
Properties used for equality comparison.
no setterinherited
- restorationId → String
-
The unique identifier for this route in the restoration system.
no setter
- restorationStrategy → RestorationStrategy
-
The restoration strategy to use for this route.
no setter
- resultValue → Object?
-
The result value passed when this route was popped.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
stackPath
→ StackPath<
RouteTarget> ? -
The StackPath that contains this route.
no setterinherited
Methods
-
bindResultValue(
Object? value) → void -
inherited
-
bindStackPath(
StackPath< RouteTarget> path) → void -
Binds the route to a path.
inherited
-
clearStackPath(
) → void -
Clears the path binding.
inherited
-
compareWith(
Object other) → bool -
Compares this object with another for equality.
inherited
-
completeOnResult(
Object? result, covariant CoordinatorCore< RouteUri> ? coordinator, [bool failSilent = false]) → void -
Completes the route's result future.
inherited
-
deepEquals(
RouteTarget other) → bool -
Whether
otheris the same lifecycle entry as this route.inherited -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
onDidPop(
Object? result, covariant CoordinatorCore< RouteUri> ? coordinator) → void -
inherited
-
onDiscard(
) → void -
Called when the route is discarded without being displayed.
inherited
-
onUpdate(
covariant RouteTarget newRoute) → void -
Called when this route is updated with state from a new route instance.
inherited
-
serialize(
) → Map< String, dynamic> - Serializes a RouteRestorable route into a map that can be persisted.
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Methods
-
deserialize<
T extends RouteTarget> (Map< String, dynamic> data, {required RouteUriParserSync<T> ? parseRouteFromUri, required RestorableConverterLookupFunction getRestorableConverter}) → T - Deserializes restoration data back into a RouteTarget instance.