Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ https://github.com/user-attachments/assets/09e96ac3-827d-4ac0-add0-e7b88ee9197c
| **tvOS** | <img src="https://github.com/user-attachments/assets/2fe8483d-73f9-408f-9315-100eee7bf2af" width="400" /> |
| **macOS** | <img src="https://github.com/user-attachments/assets/758decf4-6e70-4c55-8f2d-c16927f2c56d" width="400" /> |

> **Note:** This library uses native platform primitives which are not available on web. For web support, see the [Web Platform Support guide](https://oss.callstack.com/react-native-bottom-tabs/docs/guides/web-platform-support) in the documentation.

## Package Versions

| Name | Latest Version |
Expand Down
6 changes: 6 additions & 0 deletions docs/docs/docs/getting-started/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ React Native Bottom Tabs is a library that provides a native bottom tabs experie
- visionOS
- tvOS
- macOS

:::note

For **web** platform support, native tabs are not available. See the [Web Platform Support](/docs/guides/web-platform-support) guide for JavaScript-based alternatives.

:::
2 changes: 1 addition & 1 deletion docs/docs/docs/guides/_meta.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
["usage-with-react-navigation", "usage-with-expo-router", "usage-with-one", "standalone-usage", {"type": "divider"}, "handling-scrollview-insets", "usage-with-vector-icons", {"type": "divider"}, "android-native-styling", "edge-to-edge-support"]
["usage-with-react-navigation", "usage-with-expo-router", "usage-with-one", "standalone-usage", {"type": "divider"}, "web-platform-support", "handling-scrollview-insets", "usage-with-vector-icons", {"type": "divider"}, "android-native-styling", "edge-to-edge-support"]
168 changes: 168 additions & 0 deletions docs/docs/docs/guides/web-platform-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Web Platform Support

React Native Bottom Tabs uses native platform primitives (SwiftUI on iOS and Material Design on Android) which are not available on web. For web applications, you'll need to use JavaScript-based tab implementations as a fallback.

## How It Works

React Native's Metro bundler automatically resolves platform-specific files. You can create separate implementations for native platforms and web.

### File Structure

```
src/
├── navigation/
│ ├── TabNavigator.native.tsx # Used on iOS/Android
│ └── TabNavigator.web.tsx # Used on web
```

### Native Implementation

```tsx title="TabNavigator.native.tsx"
import { createNativeBottomTabNavigator } from '@bottom-tabs/react-navigation';
import { Platform } from 'react-native';
import { HomeScreen } from '../screens/HomeScreen';
import { SettingsScreen } from '../screens/SettingsScreen';

const Tabs = createNativeBottomTabNavigator();

export function TabNavigator() {
return (
<Tabs.Navigator>
<Tabs.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: () =>
Platform.OS === 'ios'
? { sfSymbol: 'house' }
: require('../assets/icons/home.png'),
}}
/>
<Tabs.Screen
name="Settings"
component={SettingsScreen}
options={{
tabBarIcon: () =>
Platform.OS === 'ios'
? { sfSymbol: 'gear' }
: require('../assets/icons/settings.png'),
}}
/>
</Tabs.Navigator>
);
}
```

### Web Implementation

For web, install `@react-navigation/bottom-tabs` which provides a JavaScript-based implementation:

```bash
npm install @react-navigation/bottom-tabs
```

```tsx title="TabNavigator.web.tsx"
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { HomeScreen } from '../screens/HomeScreen';
import { SettingsScreen } from '../screens/SettingsScreen';

const Tab = createBottomTabNavigator();

export function TabNavigator() {
return (
<Tab.Navigator>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: () => require('../assets/icons/home.png'),
}}
/>
<Tab.Screen
name="Settings"
component={SettingsScreen}
options={{
tabBarIcon: () => require('../assets/icons/settings.png'),
}}
/>
</Tab.Navigator>
);
}
```

### Using in Your App

Import the component normally - React Native will automatically use the correct file:

```tsx title="App.tsx"
import { NavigationContainer } from '@react-navigation/native';
import { TabNavigator } from './navigation/TabNavigator';

export default function App() {
return (
<NavigationContainer>
<TabNavigator />
</NavigationContainer>
);
}
```

## Icon Support

Icons can be provided using different methods depending on your platform:

### SF Symbols (iOS only)

```tsx
options={{
tabBarIcon: () => ({ sfSymbol: 'house' }),
}}
```

### Image Assets (PNG/SVG)

Use `require()` for PNG or SVG files. This works on iOS, Android, and web:

```tsx
options={{
tabBarIcon: () => require('../assets/icons/home.png'),
}}
```

```tsx
options={{
tabBarIcon: () => require('../assets/icons/home.svg'),
}}
```

### Cross-Platform Pattern

For a single codebase supporting iOS, Android, and web, use Platform-specific conditionals:

```tsx
import { Platform } from 'react-native';

options={{
tabBarIcon: () =>
Platform.OS === 'ios'
? { sfSymbol: 'house' }
: require('../assets/icons/home.png'),
}}
```

### Focused/Unfocused Icons

```tsx
options={{
tabBarIcon: ({ focused }) =>
focused
? require('../assets/icons/home-filled.png')
: require('../assets/icons/home-outline.png'),
}}
```

## Additional Resources

- [React Navigation Bottom Tabs](https://reactnavigation.org/docs/bottom-tab-navigator/)
- [React Native Web Documentation](https://necolas.github.io/react-native-web/)
- [Metro Bundler Platform-Specific Extensions](https://reactnative.dev/docs/platform-specific-code#platform-specific-extensions)
Loading