Creating Top Navigation Tabs in Expo Router with React Navigation

When building apps, navigation plays a huge role in the overall user experience. If your app involves bookings, tasks, or other segmented data, top navigation tabs (sliders) can help users switch between views effortlessly.

In this blog, we’ll walk through how to implement top navigation tabs in an Expo Router project using React Navigation’s Material Top Tabs. By the end, you’ll have a working setup where users can toggle between Active and History bookings.


Step 1 – Install the Required Package

First, install the @react-navigation/material-top-tabs package:

npm i @react-navigation/material-top-tabs

Step 2 – Set Up the Folder Structure

Assume your project is structured like this:

src/app/(user)/
├── _layout.tsx
├── index.tsx
└── bookings.tsx

We want to create top tabs inside bookings.tsx. For that, let’s make a new folder book inside (user) and create the following files:

src/app/(user)/book/_layout.tsx
src/app/(user)/book/index.tsx
src/app/(user)/book/history.tsx

Step 3 – Redirect the Old Bookings Page

Since we moved bookings into the book folder, we’ll redirect the old bookings.tsx to point to the new setup.

Update src/app/(user)/bookings.tsx:

import { Redirect } from 'expo-router'; 

export default function BtwoBIndex() {
  return <Redirect href={'home'} />;
}

Step 4 – Add the Top Tabs Layout

Now, let’s configure the top tabs inside src/app/(user)/book/_layout.tsx.

import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import React from 'react'; 
import { StyleSheet } from 'react-native';  
import NewBooking from './index';
import CabDuty from './cabDuty'; 
import HotelDuty from './hotelDuty'; 

const Tab = createMaterialTopTabNavigator(); 

export default function Specialroute() {
  return ( 
    <Tab.Navigator
      screenOptions={{
        tabBarScrollEnabled: true,
        tabBarItemStyle: { width: 'auto' },
        tabBarLabelStyle: { 
          textTransform: 'none',
          flexShrink: 1 
        }
      }}
      style={styles.tabContainer}
    > 
      <Tab.Screen name="index" component={NewBooking} options={{ tabBarLabel: 'New Booking' }} />  
      <Tab.Screen name="cabDuty" component={CabDuty} options={{ tabBarLabel: "Cab Duty" }} />   
      <Tab.Screen name="hotelDuty" component={HotelDuty} options={{ tabBarLabel: "Hotel Duty" }} />   
    </Tab.Navigator> 
  );
}

const styles = StyleSheet.create({
  tabContainer: { 
    flex: 1, 
  },  
});

👉 With this structure, you can add as many pages as you want to the top tabs. If they overflow, they’ll automatically become scrollable horizontally.

Step 5 – Build the Active & History Screens

Inside the book folder, add content for the two tabs:

src/app/(user)/book/index.tsx (Active Bookings):

import { StyleSheet } from 'react-native'; 
import { Text, View } from '@/src/components/Themed';

export default function ActiveBooking() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Active</Text> 
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
  }, 
});

src/app/(user)/book/history.tsx (History Bookings):

import { StyleSheet } from 'react-native'; 
import { Text, View } from '@/src/components/Themed';

export default function HistoryBooking() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>History</Text> 
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
  }, 
});

Step 6 – Improve the Bottom Tabs

Finally, let’s update the main src/app/(user)/_layout.tsx to add a clean bottom tab navigation experience.

Inside the TabLayout() return, modify like this:

return (
<Tabs>
{/* Hide old Bookings tab */}
{/* New Bookings tab */}
<Tabs.Screen
name=”book”
options={{
title: ‘Bookings’,
tabBarIcon: ({ color }) => <TabBarIcon name=”book” color={color} />,
}}
/>
</Tabs>
);

Final Thoughts

With this setup:

  • Users can switch between Active and History bookings via top tabs.
  • You can easily add more tabs (Cab Duty, Hotel Duty, etc.) without changing much code.
  • The bottom navigation stays clean, redirecting seamlessly to the new top tab system.

This modular approach keeps your codebase organized while offering users an intuitive navigation experience.

Tripti

Leave a Reply

Your email address will not be published. Required fields are marked *