I added support for both expo go and native builds in my repo but for some reason the expo router shows unmatched route on build but works fine on expo go app.
root layout:
/* eslint-disable react/react-in-jsx-scope */
// import { useReactNavigationDevTools } from '@dev-plugins/react-navigation';
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
// import { useNavigationContainerRef } from '@react-navigation/native';
import { ThemeProvider } from '@react-navigation/native';
import { SplashScreen, Stack } from 'expo-router';
import { StyleSheet } from 'react-native';
import FlashMessage from 'react-native-flash-message';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { APIProvider } from '@/api';
import { hydrateAuth, loadSelectedTheme } from '@/core';
import { useThemeConfig } from '@/core/use-theme-config';
export { ErrorBoundary } from 'expo-router';
// Import global CSS file
import '../../global.css';
// import { createNotifications } from 'react-native-notificated';
export const unstable_settings = {
initialRouteName: '(app)',
};
hydrateAuth();
loadSelectedTheme();
// Prevent the splash screen from auto-hiding before asset loading is complete.
SplashScreen.preventAutoHideAsync();
export default function RootLayout() {
// const navigationRef = useNavigationContainerRef();
// useReactNavigationDevTools(navigationRef);
return <RootLayoutNav />;
}
function RootLayoutNav() {
return (
<Providers>
<Stack>
<Stack.Screen name="(app)" options={{ headerShown: false }} />
<Stack.Screen name="onboarding" options={{ headerShown: false }} />
<Stack.Screen name="setup" options={{ headerShown: false }} />
<Stack.Screen name="otp" options={{ headerShown: false }} />
<Stack.Screen name="training" options={{ headerShown: false }} />
<Stack.Screen name="login" options={{ headerShown: false }} />
</Stack>
</Providers>
);
}
function Providers({ children }: { children: React.ReactNode }) {
const theme = useThemeConfig();
// const { NotificationsProvider } = createNotifications({
// notificationPosition: 'top-right',
// });
return (
<GestureHandlerRootView
style={styles.container}
className={theme.dark ? `dark` : undefined}
>
<ThemeProvider value={theme}>
<APIProvider>
<BottomSheetModalProvider>
{/* <NotificationsProvider /> */}
{children}
<FlashMessage position="top" />
</BottomSheetModalProvider>
</APIProvider>
</ThemeProvider>
</GestureHandlerRootView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
Tab layout:
/* eslint-disable max-lines-per-function */
/* eslint-disable react/no-unstable-nested-components */
import { Redirect, router, SplashScreen, Tabs } from 'expo-router';
import React, { useCallback, useEffect } from 'react';
import { getAllTabTitles, TabIcon } from '@/components/tab-icon';
import { useAuth } from '@/core';
import { getToken, getUser } from '@/core/auth/utils';
import {
MyAwards as MyAwardsIcon,
MyDoctor,
MyStuff as MyStuffIcon,
MyTraining as MyTrainingIcon,
} from '@/ui/icons';
export default function TabLayout() {
const tabTitles = getAllTabTitles();
const status = useAuth.use.status();
// const [isFirstTime] = useIsFirstTime();
const hideSplash = useCallback(async () => {
await SplashScreen.hideAsync();
}, []);
useEffect(() => {
if (status !== 'idle') {
setTimeout(() => {
hideSplash();
}, 1000);
}
}, [hideSplash, status]);
useEffect(() => {
const getData = async () => {
let token = await getToken();
let user = await getUser();
if (!token || !user) {
router.replace('/login');
}
};
getData();
}, []);
if (status === 'signOut') {
return <Redirect href="/login" />;
}
return (
<Tabs
screenOptions={{
tabBarStyle: { height: 70, paddingTop: 10, paddingBottom: 10 },
}}
>
<Tabs.Screen
name="index"
options={{
title: tabTitles.mytraining,
tabBarIcon: ({ focused, color }) => (
<TabIcon focused={focused}>
<MyTrainingIcon color={color} />
</TabIcon>
),
tabBarTestID: 'feed-tab',
}}
/>
<Tabs.Screen
name="settings"
options={{
title: tabTitles.mystuff,
headerShown: false,
tabBarIcon: ({ focused, color }) => (
<TabIcon focused={focused}>
<MyStuffIcon color={color} />
</TabIcon>
),
tabBarTestID: 'style-tab',
}}
/>
<Tabs.Screen
name="awards"
options={{
title: tabTitles.myawards,
headerShown: false,
tabBarIcon: ({ focused, color }) => (
<TabIcon focused={focused}>
<MyAwardsIcon color={color} />
</TabIcon>
),
tabBarTestID: 'style-tab',
}}
/>
<Tabs.Screen
name="clinic"
options={{
title: tabTitles.mydoctor,
headerShown: false,
tabBarIcon: ({ focused, color }) => (
<TabIcon focused={focused}>
<MyDoctor color={color} />
</TabIcon>
),
tabBarTestID: 'settings-tab',
}}
/>
</Tabs>
);
}
I was trying to make it work with the default exports but it seems to be breaking! I am using the initial route name aswell which might be breaking it!
Sample repo https://github.com/MohammadHarisZia/expo_sample_project