Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions docs/api/router.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Slots from '@ionic-internal/component-api/v9/router/slots.md';

<head>
<title>ion-router: Router Component to Coordinate URL Navigation</title>
<meta name="description" content="ion-router is a URL coordinator for navigation outlets of ionic: ion-nav and ion-tabs. Router components handle routing inside vanilla and Stencil JavaScript." />
<meta name="description" content="ion-router is a URL coordinator for navigation outlets of ionic: ion-tabs and ion-router-outlet. Router components handle routing inside vanilla and Stencil JavaScript." />
</head>

import EncapsulationPill from '@components/page/api/EncapsulationPill';
Expand All @@ -28,18 +28,28 @@ 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

import BasicExample from '@site/static/usage/v9/router/basic/index.md';

<BasicExample />

## 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. As of Ionic 9, `ion-nav` no longer integrates 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. Refer to the [migration guide](../updating/9-0.md#nav) for details.

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';

<NavWithinPageExample />

## Interfaces

### RouterEventDetail
Expand Down
26 changes: 26 additions & 0 deletions docs/updating/9-0.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<ion-router>
<ion-route url="/" component="page-one"></ion-route>
<ion-route url="/page-two" component="page-two"></ion-route>
</ion-router>

- <ion-nav></ion-nav>
+ <ion-router-outlet></ion-router-outlet>
```

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.
Expand Down
98 changes: 98 additions & 0 deletions static/usage/v9/router/nav-within-page/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Router | ion-nav within a Routed Page</title>
<link rel="stylesheet" href="../../common.css" />
<script src="../../common.js"></script>
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@ionic/core@8.8.14-dev.11784216165.1ecbf364/dist/ionic/ionic.esm.js"
></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@ionic/core@8.8.14-dev.11784216165.1ecbf364/css/ionic.bundle.css"
/>
</head>

<body>
<ion-app>
<!-- The router drives URL-based navigation through ion-router-outlet -->
<ion-router>
<ion-route url="/" component="page-home"></ion-route>
<ion-route url="/details" component="page-details"></ion-route>
</ion-router>

<ion-router-outlet></ion-router-outlet>

<script>
// A routed page: navigating here updates the URL to /details.
class PageHome extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<ion-header>
<ion-toolbar>
<ion-title>Home</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-router-link href="#/details">
<ion-button>Go to Details (URL changes)</ion-button>
</ion-router-link>
</ion-content>`;
}
}

// This routed page hosts its own ion-nav for a local stack.
// Pushing and popping within the ion-nav does not change the URL.
class PageDetails extends HTMLElement {
connectedCallback() {
this.innerHTML = `<ion-nav root="details-step-one"></ion-nav>`;
}
}

class DetailsStepOne extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button default-href="/"></ion-back-button>
</ion-buttons>
<ion-title>Details - Step 1</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-nav-link router-direction="forward" component="details-step-two">
<ion-button>Next step (URL stays the same)</ion-button>
</ion-nav-link>
</ion-content>`;
}
}

class DetailsStepTwo extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Details - Step 2</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
The URL is still /details. This step is managed by ion-nav, not the router.
</ion-content>`;
}
}

customElements.define('page-home', PageHome);
customElements.define('page-details', PageDetails);
customElements.define('details-step-one', DetailsStepOne);
customElements.define('details-step-two', DetailsStepTwo);
</script>
</ion-app>
</body>
</html>
11 changes: 11 additions & 0 deletions static/usage/v9/router/nav-within-page/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Playground from '@site/src/components/global/Playground';

import javascript from './javascript.md';

<Playground
version="9"
code={{ javascript }}
src="usage/v9/router/nav-within-page/demo.html"
devicePreview={true}
includeIonContent={false}
/>
77 changes: 77 additions & 0 deletions static/usage/v9/router/nav-within-page/javascript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
```html
<!-- The router drives URL-based navigation through ion-router-outlet -->
<ion-router>
<ion-route url="/" component="page-home"></ion-route>
<ion-route url="/details" component="page-details"></ion-route>
</ion-router>

<ion-router-outlet></ion-router-outlet>

<script>
// A routed page: navigating here updates the URL to /details.
class PageHome extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<ion-header>
<ion-toolbar>
<ion-title>Home</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-router-link href="#/details">
<ion-button>Go to Details (URL changes)</ion-button>
</ion-router-link>
</ion-content>`;
}
}

// This routed page hosts its own ion-nav for a local stack.
// Pushing and popping within the ion-nav does not change the URL.
class PageDetails extends HTMLElement {
connectedCallback() {
this.innerHTML = `<ion-nav root="details-step-one"></ion-nav>`;
}
}

class DetailsStepOne extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button default-href="/"></ion-back-button>
</ion-buttons>
<ion-title>Details - Step 1</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-nav-link router-direction="forward" component="details-step-two">
<ion-button>Next step (URL stays the same)</ion-button>
</ion-nav-link>
</ion-content>`;
}
}

class DetailsStepTwo extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Details - Step 2</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
The URL is still /details. This step is managed by ion-nav, not the router.
</ion-content>`;
}
}

customElements.define('page-home', PageHome);
customElements.define('page-details', PageDetails);
customElements.define('details-step-one', DetailsStepOne);
customElements.define('details-step-two', DetailsStepTwo);
</script>
```
8 changes: 4 additions & 4 deletions versioned_docs/version-v7/api/router.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Slots from '@ionic-internal/component-api/v7/router/slots.md';
<title>ion-router: Router Component to Coordinate URL Navigation</title>
<meta
name="description"
content="ion-router is a URL coordinator for navigation outlets of ionic: ion-nav and ion-tabs. Router components handle routing inside vanilla and Stencil JavaScript."
content="ion-router is a URL coordinator for navigation outlets of ionic: ion-tabs and ion-router-outlet. Router components handle routing inside vanilla and Stencil JavaScript."
/>
</head>

Expand All @@ -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

Expand Down
8 changes: 4 additions & 4 deletions versioned_docs/version-v8/api/router.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Slots from '@ionic-internal/component-api/v8/router/slots.md';
<title>ion-router: Router Component to Coordinate URL Navigation</title>
<meta
name="description"
content="ion-router is a URL coordinator for navigation outlets of ionic: ion-nav and ion-tabs. Router components handle routing inside vanilla and Stencil JavaScript."
content="ion-router is a URL coordinator for navigation outlets of ionic: ion-tabs and ion-router-outlet. Router components handle routing inside vanilla and Stencil JavaScript."
/>
</head>

Expand All @@ -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

Expand Down
Loading