Map architecture
The mapping system uses a two-layer component architecture:Despite the name
GoogleMap, this component uses Leaflet and OpenStreetMap for rendering. The naming is for interface consistency and could represent future Google Maps integration.Core map component
TheGoogleMap component provides the public API for rendering maps:
src/components/google-map.tsx
Usage example
src/app/page.tsx
Marker system
Coffee Finder displays two types of markers on the map:- User location marker
- Coffee shop markers
A distinctive blue circular marker indicates your current position:This marker:
src/components/leaflet-map-inner.tsx
- Always appears at the center initially
- Remains visible as you pan the map
- Updates when you refresh your location
- Is larger and more prominent than shop markers
Interactive popups
Clicking a coffee shop marker displays a detailed popup:src/components/leaflet-map-inner.tsx
Popup contents
Popup contents
Each popup displays:
- Shop name (bold, prominent)
- Address (muted text)
- Rating (if available, with review count)
- Distance (in meters from your location)
- Status (Open/Closed)
- Phone number (if available)
- Website link (opens in new tab)
Map controls and interactions
The map provides standard Leaflet controls:| Control | Function | User Action |
|---|---|---|
| Zoom in/out | Adjust map detail level | Click +/- buttons or scroll wheel |
| Pan | Move around the map | Click and drag |
| Click marker | View shop details | Click any coffee shop marker |
| Click map | Custom actions | Tap empty map area (optional handler) |
src/components/leaflet-map-inner.tsx
Pan to location
Coffee Finder provides apanToLocation function to smoothly navigate to specific coordinates:
src/components/google-map.tsx
- User clicks a coffee shop in the sidebar list
- Selecting a “Most Popular” or “Trending Now” featured shop
- Refreshing user location
Example usage
src/app/page.tsx
Dynamic marker generation
Markers are dynamically created from coffee shop data:src/app/page.tsx
visibleShops array changes based on the selected discovery mode (All, Popular, Trending), automatically updating map markers.
OpenStreetMap tile layer
Maps are rendered using free OpenStreetMap tiles:src/components/leaflet-map-inner.tsx
OpenStreetMap tiles are free and community-maintained. The attribution is legally required and acknowledges the OpenStreetMap contributors.
Server-side rendering (SSR) handling
Leaflet requires browser APIs and cannot render on the server. Coffee Finder uses Next.js dynamic imports:src/components/google-map.tsx
ssr: false option ensures Leaflet only loads in the browser, preventing server-side rendering errors.
Responsive sizing
The map adapts to different screen sizes:src/app/page.tsx
| Screen Size | Map Height |
|---|---|
| Mobile (< 768px) | 400px |
| Tablet (768px - 1024px) | 500px |
| Desktop (> 1024px) | 600px |
Map state management
The active map instance is stored in a module-level variable:src/components/google-map.tsx
- Programmatic map control (panning, zooming)
- Accessing map state from outside React components
- Cleanup when map is unmounted
src/components/google-map.tsx
Performance optimizations
Memoized center position
Memoized center position
src/components/leaflet-map-inner.tsx
Zoom control enabled
Zoom control enabled
src/components/leaflet-map-inner.tsx
Conditional event handlers
Conditional event handlers
src/components/leaflet-map-inner.tsx