Layout groups
This app is going to have an onboarding step. The user will be faced with a special screen when they open the app for the first time. We're not doing auth in this workshop, but you could use a similar mechanism for setting up authenticated routes.
If we defined a new screen in the app directory, it would simply get rendered as one of the bottom tabs, so we need to group the bottom tabs out of the way.
For this we can use groups. Folders with ()
are grouping folders and they don't show up as part of the route.
Move the bottom tabs in a (tabs) group
Create a new folder called (tabs) and move both screens and the layout file inside.
Add a root layout file
Now create a new app/_layout.tsx file and render the (tabs) route as a stack.
Because every screen gets rendered with a header by default, we'll need to set headerShown
to false
to avoid having duplicate headers for our tab navigator.
New file: app/_layout.tsx
import { Stack } from "expo-router";
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
</Stack>
);
}
Add the onboarding screen
Now let's create a new screen for the onboarding modal:
New file: app/onboarding.tsx
import { Text, View, StyleSheet } from "react-native";
import { theme } from "@/theme";
export default function OnboardingScreen() {
return (
<View style={styles.container}>
<Text style={styles.text}>Onboarding</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: theme.colorWhite,
},
text: {
fontSize: 24,
},
});
And the modal to the root layout:
Update app/_layout.tsx
@@ -4,7 +4,13 @@ export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
+ <Stack.Screen
+ name="onboarding"
+ options={{
+ presentation: "modal",
+ headerShown: false,
+ }}
+ />
</Stack>
);
}
Redirect
Finally, we'll use use Expo Router's Redirect component to redirect to the onboarding modal from the (tabs)/_layout.tsx:
Update (tabs)/_layout.tsx
@@ -1,9 +1,15 @@
-import { Tabs } from "expo-router";
+import { Redirect, Tabs } from "expo-router";
import Entypo from "@expo/vector-icons/Entypo";
import Feather from "@expo/vector-icons/Feather";
import { theme } from "@/theme";
+const hasFinishedOnboarding = false;
+
export default function Layout() {
+ if (!hasFinishedOnboarding) {
+ return <Redirect href="/onboarding" />;
+ }
+
return (
<Tabs screenOptions={{ tabBarActiveTintColor: theme.colorGreen }}>
<Tabs.Screen