A React 19 single-page application that looks up any IP address or domain and displays geolocation data alongside an interactive map. Built as a solution to the Frontend Mentor IP Address Tracker challenge.
- Overview
- Screenshots
- Tech Stack
- Getting Started
- Environment Variables
- Project Structure
- What I Learned
- Roadmap
- Author
Users should be able to:
- View the optimal layout for each page depending on their device's screen size (375px / 1440px)
- See hover states for all interactive elements
- See their own IP address on the map on initial page load
- Search for any IP address or domain and see the key information and map location
- Solution URL: frontendmentor.io
- Live Site URL: fsdev-ip-address-tracker-dev.vercel.app
| Layer | Technology |
|---|---|
| UI framework | React 19 |
| Language | TypeScript 5 |
| Build tool | Vite 8 |
| Map | Leaflet + react-leaflet via OpenStreetMap |
| Geolocation API | IPify Geo API v2 |
| HTTP client | Axios |
| Fonts | Rubik — Google Fonts |
- Node.js >= 18
- An IPify API key (free tier, no card required)
# 1. Clone the repository
git clone https://github.com/gusanchefullstack/fsdev-ip-address-tracker.git
cd fsdev-ip-address-tracker
# 2. Install dependencies
npm install
# 3. Configure environment variables
cp .env.example .env
# Edit .env and add your IPify API key
# 4. Start the development server
npm run devThe app will be available at http://localhost:5173.
npm run build
npm run preview| Variable | Description | Required | Default |
|---|---|---|---|
VITE_IPIFY_API_KEY |
API key from geo.ipify.org | Yes | — |
Create a .env file at the project root:
VITE_IPIFY_API_KEY=your_api_key_heresrc/
├── components/
│ ├── Header/ # Page header with background pattern and title
│ ├── SearchForm/ # IP/domain search input and submit button
│ ├── InfoCard/ # Card overlay with IP geolocation summary
│ ├── InfoItem/ # Single label + value display block
│ └── MapView/ # Leaflet map with custom location marker
├── services/
│ └── ipify.ts # IPify API client (auto-detect + manual lookup)
├── styles/
│ ├── variables.css # Design tokens (colors, spacing, typography)
│ └── global.css # CSS reset and base styles
├── types/
│ └── ip.ts # TypeScript interfaces for API response
└── App.tsx # Root component with state management
The key challenge was recentering the Leaflet map when new IP data loads without remounting the entire map component (which would cause a flash). The solution was a lightweight child component that calls useMap() inside a useEffect:
function MapRecenter({ lat, lng }: { lat: number; lng: number }) {
const map = useMap();
useEffect(() => {
map.setView([lat, lng], 13);
}, [lat, lng, map]);
return null;
}This renders as null in the DOM but imperatively drives the map view — the React way to bridge declarative state with an imperative API.
Parameterising every design value (color, spacing, radius, z-index) as CSS variables made responsive overrides trivial — only the layout values change in media queries, while all colors and typography stay consistent.
The info card overlaps the header bottom edge and the map top edge. On desktop this is achieved with position: absolute; bottom: calc(-1 * var(--card-overlap)) on the header. On mobile the card is removed from absolute flow and uses a negative margin-top instead, since the absolute approach breaks in single-column scroll layout.
The IPify API uses different query parameters for IP addresses (ipAddress) and domain names (domain). A simple regex distinguishes them:
function isDomain(query: string): boolean {
return /^(?![\d.]+$)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(query);
}Each responsive layout (desktop, tablet, mobile) was developed on its own feature branch (feature/desktop, feature/tablet, feature/mobile) and merged into main — keeping layout concerns isolated and easy to trace in git history.
- Auto-detect user IP on initial load
- Search by IP address or domain name
- Interactive Leaflet map with custom marker
- Desktop layout (1440px)
- Tablet layout (≤900px, 2-column info card)
- Mobile layout (375px, stacked info card)
- Accessible markup (single h1, semantic HTML, ARIA labels)
- Loading skeleton animation for info card
- IPv6 display support
- Search history (localStorage)
Gustavo Sanchez
- Challenge by Frontend Mentor
- Geolocation data by IPify
- Map tiles by OpenStreetMap contributors