diff --git a/docs/api/router.md b/docs/api/router.md
index 0ecfbf832f..2d7d230e6b 100644
--- a/docs/api/router.md
+++ b/docs/api/router.md
@@ -11,7 +11,7 @@ import Slots from '@ionic-internal/component-api/v9/router/slots.md';
ion-router: Router Component to Coordinate URL Navigation
-
+
import EncapsulationPill from '@components/page/api/EncapsulationPill';
@@ -28,11 +28,11 @@ The router is a component for handling routing inside vanilla and Stencil JavaSc
Apps should have a single `ion-router` component in the codebase.
This component controls all interactions with the browser history and it aggregates updates through an event system.
-`ion-router` is just a URL coordinator for the navigation outlets of ionic: `ion-nav`, `ion-tabs`, and `ion-router-outlet`.
+`ion-router` is just a URL coordinator for the navigation outlets of ionic: `ion-tabs` and `ion-router-outlet`.
-That means the `ion-router` never touches the DOM, it does NOT show the components or emit any kind of lifecycle events, it just tells `ion-nav`, `ion-tabs`, and `ion-router-outlet` what and when to "show" based on the browser's URL.
+That means the `ion-router` never touches the DOM, it does NOT show the components or emit any kind of lifecycle events, it just tells `ion-tabs` and `ion-router-outlet` what and when to "show" based on the browser's URL.
-In order to configure this relationship between components (to load/select) and URLs, `ion-router` uses a declarative syntax using JSX/HTML to define a tree of routes.
+To configure this relationship between components (to load/select) and URLs, `ion-router` uses a declarative syntax using JSX/HTML to define a tree of routes.
## Basic Usage
@@ -40,6 +40,16 @@ import BasicExample from '@site/static/usage/v9/router/basic/index.md';
+## Using ion-nav within a Routed Page
+
+`ion-router` and [`ion-nav`](./nav.md) are separate systems. `ion-router` coordinates URL-based navigation through `ion-router-outlet`, while `ion-nav` manages a local stack that is independent of the URL. `ion-nav` does not integrate with `ion-router`: placing an `ion-nav` inside an `ion-router` does not turn it into a routed outlet, and pushing or popping views on an `ion-nav` never changes the URL.
+
+The two can still be composed. A routed page rendered by `ion-router-outlet` can host its own `ion-nav` for local, URL-less navigation within that page. In the example below, navigating to `/details` updates the URL, but stepping through the `ion-nav` inside that page does not.
+
+import NavWithinPageExample from '@site/static/usage/v9/router/nav-within-page/index.md';
+
+
+
## Interfaces
### RouterEventDetail
diff --git a/docs/updating/9-0.md b/docs/updating/9-0.md
index d4194966d7..d4ad4e8239 100644
--- a/docs/updating/9-0.md
+++ b/docs/updating/9-0.md
@@ -494,6 +494,32 @@ The `autocorrect` property on `ion-searchbar` is now a `boolean` (default `false
- Remove the attribute to keep autocorrect disabled (the default).
- Use a property binding to enable it: `[autocorrect]="true"` (Angular), `autocorrect={true}` (React), or `:autocorrect="true"` (Vue).
+### Nav
+
+`ion-nav` no longer integrates with `ion-router`. It is now a standalone imperative stack navigation component, driven only through its own API (`root`, `push`, `pop`, `setRoot`, and so on) and `ion-nav-link`.
+
+This only affects apps that placed an `ion-nav` inside an `ion-router` (vanilla JavaScript projects) and relied on the router to drive it. If you use `ion-nav` on its own for local, in-page stack navigation, no changes are required.
+
+The following behaviors have been removed:
+
+- The router no longer discovers or drives an `ion-nav`. Placing an `ion-nav` inside an `ion-router` no longer turns it into a routed outlet.
+- Navigating an `ion-nav` (via `push`, `pop`, `ion-nav-link`, or the swipe-to-go-back gesture) no longer updates the URL, and the router's navigation guards no longer run for `ion-nav` transitions.
+- The `setRouteId()` and `getRouteId()` methods and the `updateURL` nav option have been removed. These existed only for the router integration.
+
+If you relied on `ion-nav` to update the URL, use `ion-router-outlet` for URL-based routing instead. Keep the `ion-route` definitions and swap the outlet element:
+
+```diff
+
+
+
+
+
+-
++
+```
+
+An `ion-nav` can still be nested inside a routed page for local, URL-less stack navigation. It manages its own stack via `root` and `ion-nav-link`, and the URL never changes as you push and pop. For a complete, working example, refer to [Using ion-nav within a Routed Page](../api/router.md#using-ion-nav-within-a-routed-page).
+
## Need Help Upgrading?
Be sure to look at the [Ionic 9 Breaking Changes Guide](https://github.com/ionic-team/ionic-framework/blob/main/BREAKING.md#version-9x) for the complete list of breaking changes. This upgrade guide only covers changes that require action from developers.
diff --git a/static/code/stackblitz/v9/html/index.ts b/static/code/stackblitz/v9/html/index.ts
index d40f179429..db4f20844b 100644
--- a/static/code/stackblitz/v9/html/index.ts
+++ b/static/code/stackblitz/v9/html/index.ts
@@ -1,6 +1,6 @@
import { defineCustomElements } from '@ionic/core/loader';
-import { createAnimation, createGesture, loadingController, menuController, modalController, pickerController, toastController } from '@ionic/core';
+import { createAnimation, createGesture, loadingController, menuController, modalController, toastController } from '@ionic/core';
/* Core CSS required for Ionic components to work properly */
import '@ionic/core/css/core.css';
@@ -37,7 +37,6 @@ defineCustomElements();
(window as any).loadingController = loadingController;
(window as any).menuController = menuController;
(window as any).modalController = modalController;
-(window as any).pickerController = pickerController;
(window as any).toastController = toastController;
(window as any).createAnimation = createAnimation;
(window as any).createGesture = createGesture;
diff --git a/static/code/stackblitz/v9/html/package-lock.json b/static/code/stackblitz/v9/html/package-lock.json
index 0759612a37..e685e020e5 100644
--- a/static/code/stackblitz/v9/html/package-lock.json
+++ b/static/code/stackblitz/v9/html/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "html-starter",
"dependencies": {
- "@ionic/core": "8.8.13",
+ "@ionic/core": "8.8.14-dev.11784216165.1ecbf364",
"ionicons": "8.0.13"
},
"devDependencies": {
@@ -50,12 +50,12 @@
}
},
"node_modules/@ionic/core": {
- "version": "8.8.13",
- "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.13.tgz",
- "integrity": "sha512-f09pRxmOLxPvLeCK9kTTBiByaPeCrApwABAwkqeax08e1b4kDSyXD1nMGDT6ChTvUGxyt4/cPxLsEP68ku4+HQ==",
+ "version": "8.8.14-dev.11784216165.1ecbf364",
+ "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.14-dev.11784216165.1ecbf364.tgz",
+ "integrity": "sha512-sWbTcctOR+vQPqoPSgzOH4dmZSom/Y0Q0FpjcY4bB5I3ECp5wf8noCebqfADv2cnmWrl6pAtWf7IZVEGcvqScw==",
"license": "MIT",
"dependencies": {
- "@stencil/core": "4.43.5",
+ "@stencil/core": "^4.43.5",
"ionicons": "^8.0.13",
"tslib": "^2.1.0"
},
diff --git a/static/code/stackblitz/v9/html/package.json b/static/code/stackblitz/v9/html/package.json
index 0b83a845f1..9d4e573c45 100644
--- a/static/code/stackblitz/v9/html/package.json
+++ b/static/code/stackblitz/v9/html/package.json
@@ -9,7 +9,7 @@
"start": "vite preview"
},
"dependencies": {
- "@ionic/core": "8.8.13",
+ "@ionic/core": "8.8.14-dev.11784216165.1ecbf364",
"ionicons": "8.0.13"
},
"devDependencies": {
diff --git a/static/usage/v9/router/nav-within-page/demo.html b/static/usage/v9/router/nav-within-page/demo.html
new file mode 100644
index 0000000000..3d043e183f
--- /dev/null
+++ b/static/usage/v9/router/nav-within-page/demo.html
@@ -0,0 +1,98 @@
+
+
+
+
+
+ Router | ion-nav within a Routed Page
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/static/usage/v9/router/nav-within-page/index.md b/static/usage/v9/router/nav-within-page/index.md
new file mode 100644
index 0000000000..3230e6ae93
--- /dev/null
+++ b/static/usage/v9/router/nav-within-page/index.md
@@ -0,0 +1,11 @@
+import Playground from '@site/src/components/global/Playground';
+
+import javascript from './javascript.md';
+
+
diff --git a/static/usage/v9/router/nav-within-page/javascript.md b/static/usage/v9/router/nav-within-page/javascript.md
new file mode 100644
index 0000000000..55b3720574
--- /dev/null
+++ b/static/usage/v9/router/nav-within-page/javascript.md
@@ -0,0 +1,77 @@
+```html
+
+
+
+
+
+
+
+
+
+```
diff --git a/versioned_docs/version-v7/api/router.md b/versioned_docs/version-v7/api/router.md
index 122a3f1744..c574f98238 100644
--- a/versioned_docs/version-v7/api/router.md
+++ b/versioned_docs/version-v7/api/router.md
@@ -13,7 +13,7 @@ import Slots from '@ionic-internal/component-api/v7/router/slots.md';
ion-router: Router Component to Coordinate URL Navigation
@@ -28,11 +28,11 @@ Note: This component should only be used with vanilla and Stencil JavaScript pro
Apps should have a single `ion-router` component in the codebase.
This component controls all interactions with the browser history and it aggregates updates through an event system.
-`ion-router` is just a URL coordinator for the navigation outlets of ionic: `ion-nav`, `ion-tabs`, and `ion-router-outlet`.
+`ion-router` is just a URL coordinator for the navigation outlets of ionic: `ion-tabs` and `ion-router-outlet`.
-That means the `ion-router` never touches the DOM, it does NOT show the components or emit any kind of lifecycle events, it just tells `ion-nav`, `ion-tabs`, and `ion-router-outlet` what and when to "show" based on the browser's URL.
+That means the `ion-router` never touches the DOM, it does NOT show the components or emit any kind of lifecycle events, it just tells `ion-tabs` and `ion-router-outlet` what and when to "show" based on the browser's URL.
-In order to configure this relationship between components (to load/select) and URLs, `ion-router` uses a declarative syntax using JSX/HTML to define a tree of routes.
+To configure this relationship between components (to load/select) and URLs, `ion-router` uses a declarative syntax using JSX/HTML to define a tree of routes.
## Basic Usage
diff --git a/versioned_docs/version-v8/api/router.md b/versioned_docs/version-v8/api/router.md
index b910f227e4..b65c14eafd 100644
--- a/versioned_docs/version-v8/api/router.md
+++ b/versioned_docs/version-v8/api/router.md
@@ -13,7 +13,7 @@ import Slots from '@ionic-internal/component-api/v8/router/slots.md';
ion-router: Router Component to Coordinate URL Navigation
@@ -28,11 +28,11 @@ Note: This component should only be used with vanilla and Stencil JavaScript pro
Apps should have a single `ion-router` component in the codebase.
This component controls all interactions with the browser history and it aggregates updates through an event system.
-`ion-router` is just a URL coordinator for the navigation outlets of ionic: `ion-nav`, `ion-tabs`, and `ion-router-outlet`.
+`ion-router` is just a URL coordinator for the navigation outlets of ionic: `ion-tabs` and `ion-router-outlet`.
-That means the `ion-router` never touches the DOM, it does NOT show the components or emit any kind of lifecycle events, it just tells `ion-nav`, `ion-tabs`, and `ion-router-outlet` what and when to "show" based on the browser's URL.
+That means the `ion-router` never touches the DOM, it does NOT show the components or emit any kind of lifecycle events, it just tells `ion-tabs` and `ion-router-outlet` what and when to "show" based on the browser's URL.
-In order to configure this relationship between components (to load/select) and URLs, `ion-router` uses a declarative syntax using JSX/HTML to define a tree of routes.
+To configure this relationship between components (to load/select) and URLs, `ion-router` uses a declarative syntax using JSX/HTML to define a tree of routes.
## Basic Usage