Does having two IonRouterOutlet make sense? One for pages one for tabs

So I what I trying to do is to set up two IonRouterOutlet

Login, Register and Tabs in one IonRouterOutlet

Tab1, Tab2 and Tab3 in another IonRouterOutlet

This way i will have tabs bar only in tabs page but not in login or register.

Works great so far except that once I added tab1Details and try to goBack it shows blank page. Same thing happens when I refresh.
Direct visit to ‘tab1’, ‘tab2’, ‘tab3’, ‘tab1Details’ all blank.
‘tabs’->‘tab1’ works ok
'tabs->‘tab1’->‘tab1Details’->‘tab1’ (by goBack) blank

Apparently I should not have IonRouterOutlet in IonRouterOutlet as warned here https://ionicframework.com/docs/react/navigation.

So how can I achieve something like show a login page then when login direct user to tabs page?

Any help will be appreciated.

App.tsx

<IonApp>
    <IonReactRouter>
      <IonRouterOutlet>
        <Route path="/" render={() => <Redirect to="/login" />} exact={true} />
        <Route path="/login" component={Login} />
        <Route path="/register" component={Register} />
      </IonRouterOutlet>
      <Route path="/tabs" component={Tabs} />
    </IonReactRouter>
  </IonApp>

Tabs.tsx

<IonReactRouter>
    <IonTabs>
      <IonRouterOutlet>
        <Route path="/tab1" component={Tab1} exact={true} />
        <Route path="/tab1Details" component={Tab1Details} />
        <Route path="/tab2" component={Tab2} exact={true} />
        <Route path="/tab3" component={Tab3} />
        <Route
          path="/tabs"
          render={() => <Redirect to="/tab1" />}
          exact={true}
        />
      </IonRouterOutlet>
      <IonTabBar slot="bottom">
        {tabs.map(({ name, route, icon }) => (
          <IonTabButton tab={name} href={route}>
            <IonIcon icon={icon} />
            <IonLabel>{name}</IonLabel>
          </IonTabButton>
        ))}
      </IonTabBar>
    </IonTabs>

I am also really confused on how we can use IonRouterOulet. Can we get some light on this issue please? No one on Ionic side is responsing :confused:

Not sure if you solved your problem but here is a solution that solves the authentication and tab navigation problems.

App.tsx

<IonApp>
      <IonReactRouter>
        <IonRouterOutlet>
          <Switch>
            <Route path="/login" component={Login} exact />
            <Route path="/" render={() => <TabContainer />} exact={true} />
            <Route path="/tabs" component={TabContainer} />
          </Switch>
        </IonRouterOutlet>
      </IonReactRouter>
  </IonApp>

Please note the use of the Switch component, without it the navigation doesn’t work as expected.

TabContainer.tsx

const TabContainer = () => {
  return (
    <IonTabs>
      <IonRouterOutlet>
        <PrivateRoute path="/tabs/tab1" component={Tab1} exact />
        <PrivateRoute path="/tabs/tab2" component={Tab2} exact />
        <Route path="/" render={() => <Redirect to="/tabs/tab1" />} exact={true} />
      </IonRouterOutlet>
      <IonTabBar slot="bottom">
        <IonTabButton tab="tab1" href="/tabs/tab1">
          <IonIcon icon={icon} />
          <IonLabel>Tab 1</IonLabel>
        </IonTabButton>
        <IonTabButton tab="tab2" href="/tabs/tab2">
          <IonIcon icon={icon} />
          <IonLabel>Tab 2</IonLabel>
        </IonTabButton>
      </IonTabBar>
    </IonTabs>
  );
};

and the final part it the PrivateRoute, which check if the user is authenticated.

PrivateRoute.tsx

export interface PrivateRouteProps extends RouteProps {
  component: any;
}

const PrivateRoute: React.SFC<PrivateRouteProps> = ({
  component: Component,
  ...props
}) => {
  // TODO: implement your own authentication here...
  const isAuthorised = true;

  // the Login route gets handled differently...
  if (props.path === "/login") {
    return isAuthorised ? (
      <Redirect to="/tabs/tab1" />
    ) : (
      <Route component={Login} />
    );
  }
  return (
    <Route
      {...props}
      render={(innerProps) => {
        return isAuthorised ? (
          <Component {...innerProps} />
        ) : (
          <Redirect to="/login" />
        );
      }}
    />
  );
};

I can’t take credit for the code, I’ve only pieced these three components together from @aaronksaunders GitHub repositories, check them out if you need more information.

2 Likes