Skip to main content
Version: 8.x

Customizing bottom tab bar

This guide covers customizing the tab bar in createBottomTabNavigator. Make sure to install and configure the library according to the installation instructions first.

Add icons for each tab

This is similar to how you would customize a stack navigator — there are some properties that are set when you initialize the tab navigator and others that can be customized per-screen in options.

Icons can be specified using the tabBarIcon option. The format of the icon varies based on the platform:

  • Local image - all platforms
  • SF Symbols name - iOS
  • Custom drawable name - Android
const RootTabs = createBottomTabNavigator({
screenOptions: {
tabBarActiveTintColor: 'tomato',
tabBarInactiveTintColor: 'gray',
},
screens: {
Home: createBottomTabScreen({
screen: HomeScreen,
options: {
tabBarIcon: Platform.select({
ios: {
type: 'sfSymbol',
name: 'house',
},
default: {
type: 'image',
source: require('./path/to/home-icon.png'),
},
}),
},
}),
Settings: createBottomTabScreen({
screen: SettingsScreen,
options: {
tabBarIcon: Platform.select({
ios: {
type: 'sfSymbol',
name: 'gear',
},
default: {
type: 'image',
source: require('./path/to/settings-icon.png'),
},
}),
},
}),
},
});

Let's dissect this:

  • tabBarIcon is a supported option in bottom tab navigator. So we know we can use it on our screen components in the options prop.
  • tabBarIcon is an object specifying the icon to display.
    • For iOS, you can use SF Symbols by setting type: 'sfSymbol' and providing the symbol name.
    • For other platforms, use type: 'image' with a source pointing to your image file. Image files must be provided for multiple screen densities (1x, 2x, 3x), e.g.: home-icon.png, [email protected], [email protected].
  • Platform.select can be used to provide different icons based on the platform.
  • The tabBarActiveTintColor and tabBarInactiveTintColor options in screenOptions control the icon and label colors. These default to the iOS platform defaults, but you can change them as shown above.
  • Read the full API reference for further information on createBottomTabNavigator configuration options.

Different icons for active and inactive states

You can also provide different icons for active and inactive states by using a function for the tabBarIcon option:

tabBarIcon: ({ focused }) => {
return {
type: 'image',
source: focused
? require('./path/to/home-filled-icon.png')
: require('./path/to/home-outline-icon.png'),
};
},

The focused parameter indicates whether the tab is active or inactive.

This not supported on Android with native implementation, the icon specified for inactive state will be used for both active and inactive states.

Using React Native Vector Icons

The React Native Vector Icons library provides a large set of icons. To use vector icons in your tab bar, we'd need to get an image source from the icon component.

First, make sure to install the appropriate icon package (e.g. @react-native-vector-icons/material-design-icons) and @react-native-vector-icons/get-image and rebuild the app after installation. Then, you can use the getImageSourceSync method to get the image source for the desired icon:

import { MaterialDesignIcons } from '@react-native-vector-icons/material-design-icons';

// ...

tabBarIcon: {
type: 'image',
source: MaterialDesignIcons.getImageSourceSync('home', 22),
},

Add badges to tab items

Sometimes we want to add badges to some tabs. You can use the tabBarBadge option to do it:

const RootTabs = createBottomTabNavigator({
screens: {
Home: createBottomTabScreen({
screen: HomeScreen,
options: {
tabBarBadge: 3,
},
}),
Settings: createBottomTabScreen({
screen: SettingsScreen,
}),
},
});

From UI perspective this component is ready to use, but you still need to find some way to pass down the badge count properly from somewhere else, like using React Context:

options: () => {
const unreadMessagesCount = use(UnreadMessagesCountContext);

return {
tabBarBadge: unreadMessagesCount,
};
};

You can also update the badge from within the screen component by using the setOptions method:

const navigation = useNavigation();

React.useEffect(() => {
navigation.setOptions({
tabBarBadge: unreadMessagesCount,
});
}, [navigation, unreadMessagesCount]);

Tabs with badges