Ionic version:
[x] 4.x
[ ] 5.x
I'm submitting a ...
[ ] bug report
[x] feature request
Current behavior:
IonReactRouter
doesn't give you the option to pass in a custom browser history. It would be great if you could do so like you can if you use the Router
component from react-router-dom
(https://reacttraining.com/react-router/web/api/Router)
Expected behavior:
To be able to use custom history like so
// history.ts
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
export default history;
// App.tsx
import { IonReactRouter } from '@ionic/react-router';
import history from './history';
const App: FC = () => (
<IonReactRouter history={history}>
{...}
</IonReactRouter>
)
I agree with you, and I am interested in a solution for that. FYI, I had recently put a bounty on an old question on Stackoverflow that you might wanna check https://stackoverflow.com/questions/55884643/ionic-4-routing-with-angular-6
Basically the situation, as I understand it, is the following:
There was a way to set browser history (or at least, navigation history) in Ionic
There is not anymore
An Angular (or React) solution is not enough to solve the problem
Another concrete use case: user needs to listen for the appUrlOpen
to intercept a Universal Link, and navigate to that component, e.g. :
# history.ts
import { createBrowserHistory } from 'history';
import { History } from 'history';
export type ReadonlyBrowserHistory = Readonly<History>
export const browserHistory: ReadonlyBrowserHistory = createBrowserHistory();
# App.tsx
import { browserHistory } from './history';
...
<IonApp>
<IonReactRouter history={browserHistory}>
<IonRouterOutlet id='main' key={String(user)}>
<Route path='/' render={() => user === null ? <LoggedOutRouter /> : <LoggedInRouter />} />
</IonRouterOutlet>
</IonReactRouter>
<Menu />
</IonApp>
# File listening for Universal Link events
import {browserHistory} from './history'
IonicApp.addListener("appUrlOpen",` (data) => {
browserHistory.push(data.url)
}
To my knowledge there's not a clean way to handle this.
IonReactRouter currently wraps BrowserRouter, which doesn't accept pre-built history.
I'll look into changing it to wrap Router instead and provide the browser stuff ourselfs.
When we can apply a custom browser history to the IonReactRouter component?
In case anyone finds this issue and is disappointed this hasn't been implemented yet, here's a quick workaround which seems to work for us.
import React from 'react'
import { History } from 'history'
import { useHistory } from 'react-router'
// Add custom property 'appHistory' to the global window object
declare global {
interface Window { appHistory: History }
}
const MyApp: React.FC = () => {
// Store the history object globally so we can access it outside of React components
window.appHistory = useHistory()
...
}
You are now able to access and mutate the history from anywhere in your app using the window.appHistory
property.
Hi @elylucas, are there any updates on this?
Another workaround that seems to be working for us (at least from initial testing):
import { useHistory } from "react-router-dom";
const SomeFunctionalComponent: React.FC = () => {
let history = useHistory();
history.push('/someRoute')
}
Hi @mogusbi and all,
There is a dev build available where you can pass in a custom history to IonReactRouter. You can give it a try by installing:
npm i @ionic/[email protected] @ionic/[email protected]
And to pass the history object:
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
<IonReactRouter history={history}>
Let me know how it works for you. If all is good this will be available in the next release.
Thanks
Hi @elylucas, this appears to be working well so far! Thank you for putting this together!
I'm going to spend a bit more time testing it but so far so good
@elylucas @mogusbi Unfortunately, it doesn't work.
If I create and pass a history object and then use it to navigate, then an empty page appears.
The useHistory
react hook also does not work.
Here is an example: https://codesandbox.io/s/bug-ionreactrouter-with-history-c6u1p?file=/src/App.tsx:1018-1086
@elylucas @mogusbi I found the problem. I installed the wrong version (v5.x.x) of the history package. For the react router v5.x.x should be used the history v4.x.x
Sorry for that. It works perfect!
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Most helpful comment
IonReactRouter currently wraps BrowserRouter, which doesn't accept pre-built history.
I'll look into changing it to wrap Router instead and provide the browser stuff ourselfs.