diff --git a/src/_data/sidenav.yml b/src/_data/sidenav.yml
index 10052f88041..7063a57b703 100644
--- a/src/_data/sidenav.yml
+++ b/src/_data/sidenav.yml
@@ -187,6 +187,8 @@
permalink: /development/platform-integration/android/androidx-migration
- title: Deprecated Splash Screen API Migration
permalink: /development/platform-integration/android/splash-screen-migration
+ - title: Restore state on Android **NEW**
+ permalink: /development/platform-integration/android/restore-state-android
- title: Targeting ChromeOS with Android
permalink: /development/platform-integration/android/chromeos
- title: iOS
@@ -206,6 +208,8 @@
permalink: /development/platform-integration/ios/platform-views
- title: iOS debugging
permalink: /development/platform-integration/ios/ios-debugging
+ - title: Restore state on iOS **NEW**
+ permalink: /development/platform-integration/ios/restore-state-ios
- title: Linux
permalink: /development/platform-integration/linux
children:
@@ -348,7 +352,7 @@
children:
- title: Debugging tools
permalink: /testing/debugging
- - title: Testing plugins **NEW**
+ - title: Testing plugins
permalink: /testing/testing-plugins
- title: Debugging apps programmatically
permalink: /testing/code-debugging
diff --git a/src/development/platform-integration/android/restore-state-android.md b/src/development/platform-integration/android/restore-state-android.md
new file mode 100644
index 00000000000..e19f39455fb
--- /dev/null
+++ b/src/development/platform-integration/android/restore-state-android.md
@@ -0,0 +1,170 @@
+---
+title: "State restoration for Android apps"
+description: "How to restore the state of your Android app after it's been killed by the OS."
+---
+
+When a user runs a mobile app and then selects another
+app to run, the first app is moved to the background,
+or _backgrounded_. The operating system (both iOS and Android)
+might kill the backgrounded app to release memory and
+improve performance for the app running in the foreground.
+
+When the user selects the app again, bringing it
+back to the foreground, the OS relaunches it.
+But, unless you've set up a way to save the
+state of the app before it was killed,
+you've lost the state and the app starts from scratch.
+The user has lost the continuity they expect,
+which is clearly not ideal.
+(Imagine filling out a lengthy form and being interrupted
+by a phone call _before_ clicking **Submit**.)
+
+So, how can you restore the state of the app so that
+it looks like it did before it was sent to the
+background?
+
+Flutter has a solution for this with the
+[`RestorationManager`][] (and related classes)
+in the [services][] library.
+With the `RestorationManager`, the Flutter framework
+provides the state data to the engine _as the state
+changes_, so that the app is ready when the OS signals
+that it's about to kill the app, giving the app only
+moments to prepare.
+
+{{site.alert.secondary}}
+ **Instance state vs long-lived state**
+ When should you use the `RestorationManager` and
+ when should you save state to long term storage?
+ _Instance state_
+ (also called _short-term_ or _ephemeral_ state),
+ includes unsubmitted form field values, the currently
+ selected tab, and so on. On Android, this is
+ limited to 1 MB and, if the app exceeds this,
+ it crashes with a `TransactionTooLargeException`
+ error in the native code.
+{{site.alert.end}}
+
+[state]: {{site.url}}/development/data-and-backend/state-mgmt/ephemeral-vs-app
+
+## Overview
+
+You can enable state restoration with just a few tasks:
+
+1. Define a `restorationId` or a `restorationScopeId`
+ for all widgets that support it,
+ such as [`TextField`][] and [`ScrollView`][].
+ This automatically enables built-in state restoration
+ for those widgets.
+
+2. For custom widgets,
+ you must decide what state you want to restore
+ and hold that state in a [`RestorableProperty`][].
+ (The Flutter API provides various subclasses for
+ different data types.)
+ Define those `RestorableProperty` widgets
+ in a `State` class that uses the [`RestorationMixin`][].
+ Register those widgets with the mixin in a
+ `restoreState` method.
+
+3. If you use any Navigator API (like `push`, `pushNamed`, and so on)
+ migrate to the API that has "restorable" in the name
+ (`restorablePush`, `resstorablePushNamed`, and so on)
+ to restore the navigation stack.
+
+Other considerations:
+
+* Providing a `restorationId` to
+ `MaterialApp`, `CupertinoApp`, or `WidgetsApp`
+ automatically enables state restoration by
+ injecting a `RootRestorationScope`.
+ If you need to restore state _above_ the app class,
+ inject a `RootRestorationScope` manually.
+
+* **The difference between a `restorationId` and
+ a `restorationScopeId`:** Widgets that take a
+ `restorationScopeID` create a new `restorationScope`
+ (a new `RestorationBucket`) into which all children
+ store their state. A `restorationId` means the widget
+ (and its children) store the data in the surrounding bucket.
+
+[a bit of extra setup]: {{site.api}}/flutter/services/RestorationManager-class.html#state-restoration-on-ios
+[`restorationId`]: {{site.api}}/flutter/widgets/RestorationScope/restorationId.html
+[`restorationScopeId`]: {{site.api}}/flutter/widgets/RestorationScope/restorationScopeId.html
+[`RestorationMixin`]: {{site.api}}/flutter/widgets/RestorationMixin-mixin.html
+[`RestorationScope`]: {{site.api}}/flutter/widgets/RestorationScope-class.html
+[`restoreState`]: {{site.api}}/flutter/widgets/RestorationMixin/restoreState.html
+[VeggieSeasons]: {{site.github}}/flutter/samples/tree/main/veggieseasons
+
+## Restoring navigation state
+
+If you want your app to return to a particular route
+that the user was most recently viewing
+(the shopping cart, for example), then you must implement
+restoration state for navigation, as well.
+
+If you use the Navigator API directly,
+migrate the standard methods to restorable
+methods (that have "restorable" in the name).
+For example, replace `push` with [`restorablePush`][].
+
+The VeggieSeasons example (listed under "Other resources" below)
+implements navigation with the [`go_router`][] package.
+Setting the `restorationId`
+values occur in the `lib/screens` classes.
+
+## Testing state restoration
+
+To test state restoration, set up your mobile device so that
+it doesn't save state once an app is backgrounded.
+To learn how to do this for both iOS and Android,
+check out [Testing state restoration][] on the
+[`RestorationManager`][] page.
+
+{{site.alert.warning}}
+ Don't forget to reenable
+ storing state on your device once you are
+ finished with testing!
+{{site.alert.end}}
+
+[Testing state restoration]: {{site.api}}/flutter/services/RestorationManager-class.html#testing-state-restoration
+[`FlutterViewController`]: {{site.api}}/objcdoc/Classes/FlutterViewController.html
+[`RestorationBucket`]: {{site.api}}/flutter/services/RestorationBucket-class.html
+[`RestorationManager`]: {{site.api}}/flutter/services/RestorationManager-class.html
+[services]: {{site.api}}/flutter/services/services-library.html
+
+## Other resources
+
+For further information on state restoration,
+check out the following resources:
+
+* For an example that implements state restoration,
+ check out [VeggieSeasons][], a sample app written
+ for iOS that uses Cupertino widgets. An iOS app requires
+ [a bit of extra setup][] in Xcode, but the restoration
+ classes otherwise work the same on both iOS and Android.
+ The following list links to relevant parts of the VeggieSeasons
+ example:
+ * [Defining a `RestorablePropery` as an instance property]({{site.github}}/flutter/samples/blob/604c82cd7c9c7807ff6c5ca96fbb01d44a4f2c41/veggieseasons/lib/widgets/trivia.dart#L33-L37)
+ * [Registering the properties]({{site.github}}/flutter/samples/blob/604c82cd7c9c7807ff6c5ca96fbb01d44a4f2c41/veggieseasons/lib/widgets/trivia.dart#L49-L54)
+ * [Updating the property values]({{site.github}}/flutter/samples/blob/604c82cd7c9c7807ff6c5ca96fbb01d44a4f2c41/veggieseasons/lib/widgets/trivia.dart#L108-L109)
+ * [Using property values in build]({{site.github}}/flutter/samples/blob/604c82cd7c9c7807ff6c5ca96fbb01d44a4f2c41/veggieseasons/lib/widgets/trivia.dart#L205-L210)
+
+* To learn more about short term and long term state,
+ check out [Differentiate between ephemeral state
+ and app state][state].
+
+* You might want to check out packages on pub.dev that
+ perform state restoration, such as [`statePersistence`][].
+
+* For more information on navigation and the
+ `go_router` package, check out [Navigation and routing][].
+
+[`RestorableProperty`]: {{site.api}}/flutter/widgets/RestorableProperty-class.html
+[`restorablePush`]: {{site.api}}/flutter/widgets/Navigator/restorablePush.html
+[`ScrollView`]: {{site.api}}/flutter/widgets/ScrollView/restorationId.html
+[`statePersistence`]: {{site.pub-pkg}}/state_persistence
+[`TextField`]: {{site.api}}/flutter/material/TextField/restorationId.html
+[`restorablePush`]: {{site.api}}/flutter/widgets/Navigator/restorablePush.html
+[`go_router`]: {{site.pub}}/packages/go_router
+[Navigation and routing]: {{site.url}}/development/ui/navigation
diff --git a/src/development/platform-integration/ios/restore-state-ios.md b/src/development/platform-integration/ios/restore-state-ios.md
new file mode 100644
index 00000000000..22d72ffa6bc
--- /dev/null
+++ b/src/development/platform-integration/ios/restore-state-ios.md
@@ -0,0 +1,25 @@
+---
+title: "State restoration on iOS"
+description: "How to restore the state of your iOS app after it's been killed by the OS."
+---
+
+When a user runs a mobile app and then selects another
+app to run, the first app is moved to the background,
+or _backgrounded_. The operating system (both iOS and Android)
+often kill the backgrounded app to release memory or
+improve performance for the app running in the foreground.
+
+You can use the [`RestorationManager`][] (and related)
+classes to handle state restoration.
+An iOS app requires [a bit of extra setup][] in Xcode,
+but the restoration classes otherwise work the same on
+both iOS and Android.
+
+For more information, check out [State restoration on Android][]
+and the [VeggieSeasons][] code sample.
+
+[a bit of extra setup]: {{site.api}}/flutter/services/RestorationManager-class.html#state-restoration-on-ios
+[`RestorationManager`]: {{site.api}}/flutter/services/RestorationManager-class.html
+[State restoration on Android]: {{site.url}}/development/platform-integration/android/restore-state-android
+[VeggieSeasons]: {{site.github}}/flutter/samples/tree/main/veggieseasons
+