short version:
I would like to have the same IonMenu
in all my IonPages
. Is there a way to move the menu above the pages, maybe next to the routing?
How do I set this up properly?
Detailed version:
My app has an IonMenu
that is used to navigate between routes. It has a list of entries, each of them an IonItem
that links to a route like ‘/home’, ‘/config’, etc.
Here’s a mock up of the current state
<router>
<route path="/home">
<lots of layout code for the menu>
<page>
</route>
<route path="/about">
<same menu code again>
<another page>
</route>
...
</router>
So this is horrible code duplication, the same code for the menu is duplicated on each page.
As far as I can see, there would be two solutions:
- make a custom component for the menu. Then it’s only a single tag (and I would have to pass in the content-id via props)
- move the menu up, above the router
I would prefer the second solution. Because the menu really is the same everywhere, it doesn’t depend on the routes. So I think it should be specified outside of the routing, as a sibling to the router. That would mirror the structure of the UI.
As far as I understand, there are the following requirements:
- The
IonMenu
needs to be given acontentId
. I think this should beIonRouterOutlet
. The contentId specifies an element on which to listen for swipe actions. And I want that element to be the output of the routing. - There needs to be a toolbar with the
IonMenuButton
. I think this should go into anIonHeader
. Intuitively I would place this header next to the IonMenu, as another sibling to the router. But the documentation says that: It’s important to note that ion-header needs to be the one of the three root elements of a page. And I’ve got the impression that they mean an actual literalIonPage
here. - Every Route must be an IonPage and IonPages must not be nested inside of each other.
I tried placing the IonHeader next to the routing, but then the pages and the header overlap each other. This doesn’t seem to work. So I moved the header inside of the IonPage and came up with the following code (simplified to provide a minimal example):
App.tsx:
<IonApp>
<IonMenu side="start" contentId="main-content">
<IonList>
<IonItem routerLink="/home">
<IonLabel>home</IonLabel>
</IonItem>
<IonItem routerLink="/config">
<IonLabel>config</IonLabel>
</IonItem>
</IonList>
</IonMenu>
<IonReactRouter>
<IonRouterOutlet id='main-content'>
<Route path="/home" component={Home} exact={true} />
<Route path="/config" component={Config} exact={true} />
<Route exact path="/" render={() => <Redirect to="/home" />} />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
Home.tsx:
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonMenuButton></IonMenuButton>
</IonButtons>
<IonTitle>Routing Menu</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<IonButton routerLink="/config">To the config!</IonButton>
</IonContent>
</IonPage>
Config.tsx (this one without the menubar)
<IonPage>
<IonContent>
<IonButton routerLink='/home'>To the home!</IonButton>
</IonContent>
</IonPage>
This code doesn’t work. If I transition between routes with the buttons, they are changed properly, with a small animation. But if the menu is used for navigation, the page flickers and seems to re-render completely. There is no transition animation between the pages.
What is the correct way to do this?