A modern, responsive web application built with Nuxt 4 that allows users to explore countries around the world. This project was developed as part of an interview task, featuring country browsing, detailed country information, search and filtering capabilities, and a beautiful dark/light theme toggle.
- ✅ Vue 3 with TypeScript: Built using Vue 3 Composition API with full TypeScript support
- ✅ REST Countries V2 API Integration: Fetches country data from the official API
- ✅ Homepage with All Countries: Displays all countries from the API
- ✅ Search Functionality: Real-time search by country name
- ✅ Region Filtering: Filter countries by geographical regions
- ✅ Client-side Routing: Dynamic country detail pages with navigation
- ❌ Border Country Navigation: Click on border countries to navigate to their details (Because Borders are abbreviation of countries and we couldn't find country from border key)
- ✅ Dark/Light Mode Toggle: Custom theme switcher without 3rd party libraries
- ❌ Smart Search: Handles typos (e.g., "Grmany" or "Grmny" finds "Germany")
- ✅ Sort Functionality: Sort by Population and Country Name
- ✅ Server-Side Rendering: Full SSR with error fallbacks
- ✅ Optimized Flag Ratios: Country flags maintain proper 4:3 aspect ratio
- ✅ URL Query Synchronization: All filters persist in URL and sync with components
- ❌ Lazy Loading: Images and country list with lazy loading for performance
-
Real-time Search: Search countries by name with instant results
-
Region Filtering: Filter countries by geographical regions (Africa, Americas, Asia, Europe, Oceania)
-
Smart Sorting: Sort by country name (alphabetical) or population (descending)
-
URL Synchronization: All filters persist in URL and work after page refresh
- Dark/Light Mode: Toggle between themes with smooth transitions
- Persistent Theme: Theme preference saved in localStorage
- System Theme Detection: Automatically detects user's system preference
- No 3rd Party Libraries: Custom implementation using CSS custom properties
- Mobile-First: Optimized for all screen sizes (mobile, tablet, desktop)
- Grid Layouts: Responsive country cards that adapt to screen size
- Touch-Friendly: Large touch targets and smooth interactions
- Modern UI: Clean, minimalist design matching the provided designs
- Comprehensive Details: Population, region, capital, currencies, languages, native names
- Flag Images: High-quality country flags with lazy loading and proper 4:3 aspect ratio
- Border Countries: Navigate to neighboring countries with clickable buttons
- Server-Side Rendering: Fast initial page loads with SSR
- Framework: Nuxt 4 - Vue.js meta-framework with SSR
- Language: TypeScript - Type-safe JavaScript
- Styling: Tailwind CSS - Utility-first CSS framework
- Icons: Heroicons - Beautiful hand-crafted SVG icons
- API: REST Countries V2 API - Free countries data
- Deployment: Vercel - Serverless deployment platform
countries-app/
├── app/
│ ├── components/ # Reusable Vue components
│ │ ├── cards/ # Card components (Country)
│ │ ├── form/ # Form components (Input, Select, Button)
│ │ └── UI/ # UI components (Error, Loading, TitleValue)
│ ├── composables/ # Vue composables for shared logic
│ │ ├── useFilter.ts # Filtering, sorting, and URL sync logic
│ │ └── useTheme.ts # Theme management and persistence
│ ├── layouts/ # Page layouts
│ │ └── default.vue # Main app layout with theme toggle
│ ├── pages/ # File-based routing
│ │ ├── index.vue # Home page with country list and filters
│ │ └── [countryName]/ # Dynamic country detail pages
│ ├── types/ # TypeScript type definitions
│ └── utils/ # Utility functions (number formatting)
├── public/ # Static assets
└── nuxt.config.ts # Nuxt configuration
- Cards Components: Country display components (
Country.vue) - Form Components: Input and selection components (
Input,Select,Button) - UI Components: Reusable UI elements (
Error,Loading,TitleValue)
useFilter: Manages search, sorting, and filtering with URL synchronizationuseTheme: Handles dark/light theme switching and persistence
/: Home page with country list, search, filters, and sorting/[countryName]: Dynamic country detail pages with border country navigation
- Node.js 18+
- pnpm (recommended) or npm
-
Clone the repository
git clone <repository-url> cd countries-app
-
Install dependencies
pnpm install
-
Start development server
pnpm dev
-
Open your browser Navigate to
http://localhost:3000
# Build the application
pnpm build
# Preview production build
pnpm preview
# Generate static site
pnpm generate- Search: Type in the search box to find countries by name (handles typos)
- Filter by Region: Use the region dropdown to filter by geographical area
- Sort: Choose to sort by name (A-Z) or population (highest to lowest)
- Theme Toggle: Click the theme button in the header to switch between dark/light mode
- Navigation: Click on any country card to view detailed information
- Back Button: Use the back button to return to the country list
- Border Countries: Click on border country buttons to navigate to neighboring countries
- Comprehensive Info: View population, region, capital, currencies, languages, and more
- Shareable Links: All filters are synced with URL parameters
- Bookmarkable: Save filtered views as bookmarks
- Browser History: Use browser back/forward buttons with filters intact
// nuxt.config.ts
runtimeConfig: {
public: {
API_URL: 'https://restcountries.com/v3.1',
},
}- Colors: Modify CSS custom properties in
main.css - Fonts: Change font family in
nuxt.config.ts - API: Update API endpoint in runtime config
- Styling: Customize Tailwind classes and component styles
- Mobile Design: Responsive design matching mobile mockups
- Desktop Design: Desktop layout matching provided designs
- Dark Mode: Custom dark theme implementation
- Light Mode: Clean light theme matching designs
- Typography: Font sizes and spacing based on design files
- Color Palette: Colors extracted from design files
- Mobile: 320px - 768px
- Tablet: 768px - 1024px
- Desktop: 1024px+
The application is deployed on Vercel with the following features:
- Automatic Deployments: Deploys on every push to main branch
- Server-Side Rendering: Full SSR support
- Edge Functions: Global CDN for fast loading
- Custom Domain: Available at the provided URL
# Production build
pnpm build
# Static generation
pnpm generate
# Preview locally
pnpm preview- REST Countries API for providing free country data
- Nuxt.js for the amazing Vue.js framework
- Tailwind CSS for the utility-first CSS framework
- Heroicons for the beautiful icon set
- Vercel for the deployment platform
Built with ❤️ using Nuxt 4, Vue 3, and TypeScript for the Journey Mentor interview task