Skip to content
Back to skills

076 App A62b3f4e

ASecurity

``` app/ ├── _layout.tsx # Root layout ├── index.tsx # Home (/) ├── +not-found.tsx # 404 page ├── (tabs)/ # Tab group │ ├── _layout.tsx # Tab bar config │ ├── index.tsx # First tab │ └── profile.tsx # Profile tab ├── (auth)/ # Auth group (no tabs) │ ├── _layout.tsx │ ├── login.tsx │ └── register.tsx ├── settings/ │ ├── _layout.tsx # Stack layout │ ├── index.tsx # Settings main │ └── notif

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 31, 2026
developmenttypescriptgoreact

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 31, 2026

npx -y skills add tools-only/X-Skills --skill 076-app_a62b3f4e --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 076 App A62b3f4e?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 076 App A62b3f4e
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-076-app-a62b3f4e/badge)](https://www.skillsdirectory.com/skills/tools-only-076-app-a62b3f4e)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Expo Router

## Project Structure

```
app/
├── _layout.tsx           # Root layout
├── index.tsx             # Home (/)
├── +not-found.tsx        # 404 page
├── (tabs)/               # Tab group
│   ├── _layout.tsx       # Tab bar config
│   ├── index.tsx         # First tab
│   └── profile.tsx       # Profile tab
├── (auth)/               # Auth group (no tabs)
│   ├── _layout.tsx
│   ├── login.tsx
│   └── register.tsx
├── settings/
│   ├── _layout.tsx       # Stack layout
│   ├── index.tsx         # Settings main
│   └── notifications.tsx
└── details/[id].tsx      # Dynamic route
```

## Root Layout

```typescript
// app/_layout.tsx
import { Stack } from 'expo-router';
import { ThemeProvider } from '@react-navigation/native';

export default function RootLayout() {
  return (
    <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
      <Stack screenOptions={{ headerShown: false }}>
        <Stack.Screen name="(tabs)" />
        <Stack.Screen name="(auth)" />
        <Stack.Screen
          name="details/[id]"
          options={{ presentation: 'modal' }}
        />
      </Stack>
    </ThemeProvider>
  );
}
```

## Tab Layout

```typescript
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';

export default function TabLayout() {
  return (
    <Tabs
      screenOptions={{
        tabBarActiveTintColor: '#007AFF',
        headerShown: true,
      }}
    >
      <Tabs.Screen
        name="index"
        options={{
          title: 'Home',
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="home" color={color} size={size} />
          ),
        }}
      />
      <Tabs.Screen
        name="profile"
        options={{
          title: 'Profile',
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="person" color={color} size={size} />
          ),
        }}
      />
    </Tabs>
  );
}
```

## Navigation

```typescript
import { router, useLocalSearchParams, Link } from 'expo-router';

// Programmatic navigation
router.push('/details/123');           // Push to stack
router.replace('/home');               // Replace current
router.back();                          // Go back
router.canGoBack();                     // Check if can go back

// With params
router.push({
  pathname: '/details/[id]',
  params: { id: '123', title: 'Item' },
});

// Link component
<Link href="/profile" asChild>
  <Pressable>
    <Text>Go to Profile</Text>
  </Pressable>
</Link>

// Reading params
function DetailsScreen() {
  const { id, title } = useLocalSearchParams<{ id: string; title?: string }>();
  return <Text>Details for {id}</Text>;
}
```

## Protected Routes

```typescript
// app/(auth)/_layout.tsx
import { Redirect, Stack } from 'expo-router';
import { useAuth } from '@/hooks/useAuth';

export default function AuthLayout() {
  const { user, isLoading } = useAuth();

  if (isLoading) {
    return <LoadingScreen />;
  }

  if (user) {
    return <Redirect href="/(tabs)" />;
  }

  return <Stack screenOptions={{ headerShown: false }} />;
}

// app/(tabs)/_layout.tsx
export default function TabLayout() {
  const { user, isLoading } = useAuth();

  if (isLoading) {
    return <LoadingScreen />;
  }

  if (!user) {
    return <Redirect href="/(auth)/login" />;
  }

  return <Tabs>...</Tabs>;
}
```

## Deep Linking

```json
// app.json
{
  "expo": {
    "scheme": "myapp",
    "web": {
      "bundler": "metro"
    }
  }
}
```

```typescript
// Handle: myapp://details/123
// app/details/[id].tsx handles automatically
```

## Quick Reference

| Component | Purpose |
|-----------|---------|
| `<Stack>` | Stack navigator |
| `<Tabs>` | Tab navigator |
| `<Drawer>` | Drawer navigator |
| `<Link>` | Declarative navigation |

| router method | Behavior |
|---------------|----------|
| `push()` | Add to stack |
| `replace()` | Replace current |
| `back()` | Go back |
| `dismissAll()` | Dismiss modals |

Files in this skill

  • README.md931 B
  • skill.md4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…