The UK Travel Recommendation frontend is a cross-platform mobile application built with Expo SDK 54 and React Native 0.81.5. It delivers a swipe-based attraction discovery experience backed by vector-embedding recommendations from the Django REST API. The app is structured around three distinct navigation stacks — authentication, onboarding, and the main tabbed interface — with TanStack Query v5 managing all server state, anDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/viet2811/uk-travel-recommendation/llms.txt
Use this file to discover all available pages before exploring further.
AuthContext handling JWT lifecycle, and NativeWind providing a Tailwind-compatible utility styling layer throughout.
Tech Stack
The following core libraries underpin the application:| Library | Version | Purpose |
|---|---|---|
| expo | ^54.0.0 | Build tooling, OTA updates, native module access |
| react-native | 0.81.5 | Cross-platform UI primitives |
| react | 19.1.0 | Component model and concurrent rendering |
| nativewind | latest | Utility-class styling for React Native |
| tailwindcss | ^3.4.0 | Tailwind CSS compiler used by NativeWind |
| @tanstack/react-query | ^5.90.21 | Server-state fetching, caching, and invalidation |
| @react-navigation/native | ^7.1.28 | Stack and bottom-tab navigation |
| axios | ^1.13.5 | HTTP client with request/response interceptors |
| expo-secure-store | ~15.0.8 | Encrypted JWT storage on device |
| @react-native-async-storage/async-storage | 2.2.0 | Persistent geo filter preference |
| react-native-maps | 1.20.1 | Interactive map view for liked attractions |
| @gorhom/bottom-sheet | ^5 | Attraction detail sheet on discovery cards |
| lucide-react-native | ^0.563.0 | Icon set |
| react-native-reanimated | 4.1.1 | Animation libraries, used for custom swiping animation |
| react-native-gesture-handler | 2.28.0 | Handling mobile gesture: swipe, scroll, ..etc |
Navigation Structure
The app uses a single rootNativeStackNavigator whose screens branch into three logical groups. Unauthenticated users land in the Auth stack, complete the Preference onboarding stack on first sign-up, and then enter the Main bottom-tab stack for everyday use.
types/navigation.tsx:
LikedAreaScreen is the only parameterised route. It receives an array of Attraction objects and the name of the selected area so the map view can be pre-filtered without an additional network request.State Management
State in the app is deliberately split by concern:TanStack Query
Manages all server-originated state: the paginated recommendations feed, the liked-attractions history, and search results. Stale-while-revalidate semantics keep the UI snappy while background refreshes run automatically.
AuthContext
Wraps the entire app and exposes
isAuthenticated, isLoading, login(), and logout(). Tokens are persisted in expo-secure-store and rehydrated on every cold start.AsyncStorage
Stores the user’s geo filter string (e.g.
?area=London). This lightweight preference does not need the encryption that SecureStore provides but does need to survive app restarts.Local Component State
Ephemeral UI state — sheet open/close, form field values, swipe deck index — lives in plain React
useState and never escapes the component tree.Theming
Styling is handled by NativeWind, which compiles Tailwind CSS utility classes down to React NativeStyleSheet objects at build time. Custom design tokens are declared in theme/colors.ts and made available as Tailwind colour names throughout the app:
Key Dependencies
Expo
Provides the managed build workflow, OTA update infrastructure, and access to native APIs (SecureStore, Camera, Location) without requiring a custom native build for development.
TanStack Query v5
Infinite query support powers the paginated recommendations feed. The
useRecommendations hook triggers the next page fetch automatically when five or fewer cards remain in the deck.NativeWind
Brings the full Tailwind CSS v3 utility vocabulary to React Native. Combined with the custom colour tokens, it eliminates bespoke
StyleSheet boilerplate across the entire codebase.React Navigation
Handles both the root native stack (for full-screen transitions) and the bottom-tab bar inside the
Main screen. Deep linking and type-safe route params are configured via RootStackParamList.react-native-maps
Renders the
LikedAreaScreen map, plotting liked attractions as map markers. On iOS it uses Apple Maps; on Android it defaults to Google Maps.react-native-animated & react-native-gesture-handler
Powers the
DiscoveryScreen card deck. Left swipes trigger dislikeAttraction, right swipes trigger likeAttraction, and the deck automatically re-fills from the TanStack Query infinite cache.Running the Frontend
Follow these steps to start the development server locally:Configure the backend URL
Create a Use your machine’s LAN IP address (not
.env file (or .env.local) in the frontend project root and set the Expo public environment variable that points to your running Django backend:localhost) so that a physical device or emulator can reach the backend.Start the Expo development server