Skip to content

Conversation

@ShaneK
Copy link
Member

@ShaneK ShaneK commented Dec 2, 2025

Issue number: resolves #24177


What is the current behavior?

Currently, Ionic Framework React Router only supports React Router 5. This has many issues and unsupported/broken features.

What is the new behavior?

With this change, Ionic Framework will support React Router 6 while still supporting transitions in the same way a native app does.

Most of what caused this change to take a long time is that React Router 5 and React Router 6 have fundamental differences in how they handle components once they're no longer part of the view. In this change, we move away from relying on React Router directly so much and have our own implementation for deciding how views get dealt with during navigation and when they're cleaned up, allowing for us to still transition between them like we need to while still using React Router as much as we possibly can.

This change will also lay the foundation for the migration to React Router 7, which will ideally be easier since most of the hard work has been dealt with here.

Does this introduce a breaking change?

  • Yes
  • No

Other information

Current dev build:

⚠️ WARNING: If you're going to use this dev build on an existing react project, you'll need to migrate to React Router 6. Migrating a large project at this point might be a bad idea since this will not release until v9, which will require further migrations and have other breaking changes! I do not currently have migration documentation for this, but it's a relatively easy process from the migrations I've been doing.

8.7.13-dev.11765426479.16a61ecf

thetaPC and others added 30 commits May 8, 2025 14:49
Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com>
…ter 6

Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com>
…ct router 6

Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com>
… router 6

Co-authored-by: Sean Perkins <13732623+sean-perkins@users.noreply.github.com>
@mhartington
Copy link
Contributor

Took you long enough...Good job shane

fail-fast: false
matrix:
apps: [reactrouter5]
apps: [reactrouter6]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should either update the breaking changes file to include no longer supporting react router 5 or create a follow-up task since doing so might conflict with next: https://github.com/ionic-team/ionic-framework/blob/next/BREAKING.md

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I still need to document migration strategies and such. For the most part, it's a pretty easy migration (ignore the inline overlay stuff, that was all removed), but I just need to write it out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and did this in this branch, figuring it would be an easy enough merge conflict resolution. If you'd like to review in an easier to read way:
https://github.com/ionic-team/ionic-framework/blob/b2a71050344052a4858d0c8b6712f0d5bc9d7219/BREAKING.md

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ShaneK ShaneK mentioned this pull request Dec 3, 2025
3 tasks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be beneficial to add to main now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this for personal usage?

Copy link
Member Author

@ShaneK ShaneK Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I also think it's good for everyone in the same way sync is. It does a lot of the annoying work of building and starting the server and killing the old one for you, which makes iteration much nicer. I 100% intend to commit this to main.

I'll probably create similar scripts for the other packages as we go.

* @param options The options for computing the parent path.
* @returns The computed parent path result.
*/
export const computeParentPath = (options: ComputeParentPathOptions): ParentPathResult => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can split some of the logic of computeParentPath to smaller functions so it's easier to digest the if statements.

Comment on lines +107 to +124
useEffect(() => {
const activeView = viewStack.current.findViewItemByRouteInfo(routeInfo, undefined, true);
const matchedParams = activeView?.routeData.match?.params as RouteParams | undefined;

if (matchedParams) {
const paramsCopy = filterUndefinedParams({ ...matchedParams });
if (areParamsEqual(routeInfo.params as RouteParams | undefined, paramsCopy)) {
return;
}
} else {
this.handleNavigate(pathname, 'push', 'none', undefined, routeOptions, tab);

const updatedRouteInfo: RouteInfo = {
...routeInfo,
params: paramsCopy,
};
locationHistory.current.update(updatedRouteInfo);
setRouteInfo(updatedRouteInfo);
}
}
}, [routeInfo]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a comment of what this is doing.

<IonHeader>
<IonToolbar>
<IonTitle>Main</IonTitle>
<IonTitle>Test App - React Router v{majorVersion}</IonTitle>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this change on main.

Comment on lines 82 to 83
// cy.get('ion-menu.show-menu').should('exist');
// cy.wait(1000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get rid of the commented out code.

this.ionLifeCycleContext = context;
return (
<StackManager routeInfo={routeInfo}>
<StackManager routeInfo={routeInfo} id={id}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick

Suggested change
<StackManager routeInfo={routeInfo} id={id}>
<StackManager id={id} routeInfo={routeInfo}>

Comment on lines 95 to +96
setRef={(val: HTMLIonRouterOutletElement) => (this.ionRouterOutlet = val)}
id={id}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick

Suggested change
setRef={(val: HTMLIonRouterOutletElement) => (this.ionRouterOutlet = val)}
id={id}
id={id}
setRef={(val: HTMLIonRouterOutletElement) => (this.ionRouterOutlet = val)}


# Install Dependencies
npm install *.tgz --no-save
npm install *.tgz --no-save --legacy-peer-deps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a note of why legacy-peer-deps is needed and a TODO to remove it when possible.

…gation (#30854)

Issue number: resolves internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
When switching between tabs using the tab bar in a React Router 6
application, clicking IonBackButton incorrectly navigates back to the
previous tab. Each tab should have its own isolated navigation history
stack, and the back button should only navigate within the current tab's
history.

## What is the new behavior?

Tab navigation history is now properly isolated. When switching tabs via
the tab bar:
  - The back button only navigates within the current tab's history
- Pressing back on a tab root (with no navigation history) does nothing
instead of navigating to the previous tab or default route
- Within-tab navigation continues to work correctly (e.g., navigating to
a details page and back)
  - Tab history is preserved when switching away and returning to a tab

## Does this introduce a breaking change?

- [ ] Yes
- [X] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

Current dev build:
```
8.7.12-dev.11765377112.16762e5b
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: react @ionic/react package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants