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.