IP Address Tracker with HTML, CSS & JavaScript

30 DAYS 30 PROJECT CHALLENGE

Day #29

Project Overview

The IP Address Tracker is a beginner-friendly project built with HTML, CSS, and JavaScript. It allows users to find geographical and network information for an IP address. The application uses public IP services to retrieve the IP address and then fetch additional details such as the city, region, country, ISP, and timezone.

Additionally, the application displays a loading message while it processes the request and provides error messages when the IP cannot be detected or its details cannot be fetched. Therefore, this project gives beginners practical experience with multiple API requests, asynchronous JavaScript, JSON data, conditional logic, and dynamic HTML rendering.

Key Features

  • IP Address Tracking: Users can enter an IP address and retrieve information related to it. The application sends the entered address to the geographical lookup service and displays the returned details.
  • Geolocation API Integration: This project uses the GeoJS API to retrieve geographical and network information for the selected IP address. Therefore, users can see more details than just the IP number.
  • City and Region Details: Result displays the city and region associated with the IP address. This helps users understand the approximate geographical information returned by the API.
  • Country Information: The application also displays the country associated with the IP address. JavaScript retrieves this value from the country property in the API response.
  • ISP Information: It shows the organization or ISP associated with the IP address. This information comes from the organization property returned by GeoJS.
  • Timezone Display: It displays the timezone associated with the IP address. As a result, users can view another useful piece of geographical information from the API response.
  • Loading Feedback: The result area immediately displays "Loading..." when the user starts tracking an IP. This gives users feedback while the API request is being processed.
  • Two-Step API Request: When the user does not provide an IP, JavaScript first calls IPify to find the public IP and then passes that IP to the GeoJS API. This demonstrates how one API response can become the input for another request.
  • Custom IP Search: This project allows the user to enters an IP address, and then theĀ  application skips the automatic detection step and directly calls fetchGeo() with the provided address. Therefore, users can look up a specific IP as well.
  • Error Handling: It also handles failures during both IP detection and geographical lookup. It displays a clear error message instead of leaving the result section empty.
  • Dynamic Results: JavaScript creates the result content after receiving the API response. The displayed IP, city, region, country, ISP, and timezone therefore change according to the returned data.
  • Simple User Interface: This project uses a clean centered card with a search field, Track button, and result area. This keeps the interface simple while still presenting several pieces of IP information.

What You'll Learn

  • Learn how to work with public IP and geolocation APIs.
  • How to use fetch() for asynchronous API requests.
  • Understand how to make one API request based on the result of another API request.
  • How to read values from an input using .value.
  • How to use conditional logic to handle optional user input.
  • How to convert API responses into JSON with res.json().
  • How to pass data between JavaScript functions.
  • How to use template literals to generate dynamic HTML.
  • Know how to display API data using innerHTML.
  • How to handle successful and failed API requests.
  • How to work with properties such as ip, city, region, country, organization, and timezone.

HTML Code

HTML creates the basic structure of the IP Address Tracker. The .ip-container holds the complete application, while the <h2> displays the project title. Inside the .search-box, the #ipInput field allows users to enter an IP address, while the placeholder also indicates that the field is optional.

Next, the Track button calls the trackIP() function when clicked and the #result element starts empty and provides the area where JavaScript displays the loading message, IP details, or error message. Finally, the page loads script.js after the main HTML structure so the JavaScript can access the required elements.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>IP Address Tracker</title>
  <link rel="stylesheet" href="style.css" />
</head>
<body>

  <div class="ip-container">
    <h2>IP Address Tracker</h2>

    <div class="search-box">
      <input
        type="text"
        id="ipInput"
        placeholder="Enter IP address (optional)"
      />
      <button onclick="trackIP()">Track</button>
    </div>

    <div id="result" class="result"></div>
  </div>

  <script src="script.js"></script>
</body>
</html>

CSS Code

CSS controls the layout and appearance of the IP Address Tracker. The universal * selector sets box-sizing: border-box and applies the Segoe UI font, while the body uses Flexbox to center the tracker against the dark blue background.

This .ip-container creates the main white card with a fixed width, padding, rounded corners, centered text, and a shadow. Next, .search-box uses Flexbox to keep the input and Track button together, while flex: 1 allows the input to use the available space.

Then the .result class adds spacing and aligns the returned information to the left. The .result p selector adds consistent spacing between each detail, while the .error class displays failed requests in red and centers the message.

* {
  box-sizing: border-box;
  font-family: "Segoe UI", sans-serif;
}

body {
  min-height: 100vh;
  background: #042453;
  display: flex;
  justify-content: center;
  align-items: center;
}

.ip-container {
  background: #ffffff;
  width: 360px;
  padding: 25px;
  border-radius: 14px;
  text-align: center;
  box-shadow: 0 20px 40px rgba(0,0,0,0.25);
}

h2 {
  margin-bottom: 15px;
}

.search-box {
  display: flex;
  margin-bottom: 15px;
}

.search-box input {
  flex: 1;
  padding: 10px;
  border-radius: 6px 0 0 6px;
  border: 1px solid #ccc;
}

.search-box button {
  padding: 10px 16px;
  border: none;
  border-radius: 0 6px 6px 0;
  background: #4f46e5;
  color: white;
  cursor: pointer;
}

.result {
  margin-top: 15px;
  text-align: left;
  font-size: 14px;
}

.result p {
  margin: 6px 0;
}

.error {
  color: red;
  text-align: center;
}

Javascript Code

JavaScript handles the complete IP tracking process through the trackIP() and fetchGeo() functions. First, trackIP() reads the value from #ipInput and displays "Loading...". If the user enters an IP address, the function directly calls fetchGeo(inputIP).

However, when the input is empty, the code sends a request to the IPify API using fetch("https://api.ipify.org?format=json"). After res.json() converts the response into JavaScript data, the returned data.ip value is passed to fetchGeo(). If that request fails, the application displays "Unable to detect IP".

The fetchGeo(ip) function then sends the IP address to the GeoJS API. After receiving the response, it displays the IP, city, region, country, ISP, and timezone inside the #result element. Finally, its .catch() block displays "Unable to fetch IP details" when the geographical lookup fails.

const result = document.getElementById("result");

function trackIP() {
  const inputIP = document.getElementById("ipInput").value.trim();

  result.innerHTML = "Loading...";

  // If user enters IP, use it. Otherwise auto-detect.
  if (inputIP) {
    fetchGeo(inputIP);
  } else {
    fetch("https://api.ipify.org?format=json")
      .then(res => res.json())
      .then(data => fetchGeo(data.ip))
      .catch(() => {
        result.innerHTML = "<p class='error'>Unable to detect IP</p>";
      });
  }
}

function fetchGeo(ip) {
  fetch(`https://get.geojs.io/v1/ip/geo/${ip}.json`)
    .then(res => res.json())
    .then(data => {
      result.innerHTML = `
        <p><strong>IP:</strong> ${data.ip}</p>
        <p><strong>City:</strong> ${data.city}</p>
        <p><strong>Region:</strong> ${data.region}</p>
        <p><strong>Country:</strong> ${data.country}</p>
        <p><strong>ISP:</strong> ${data.organization}</p>
        <p><strong>Timezone:</strong> ${data.timezone}</p>
      `;
    })
    .catch(() => {
      result.innerHTML = "<p class='error'>Unable to fetch IP details</p>";
    });
}
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Related Projects

Day 26 : Job Search App (API)

Searches and displays job listings dynamically using a public jobs API.

Concepts: API integration, async data fetching, dynamic UI rendering.

Day 27 : Recipe Finder App

Searches and displays recipes dynamically using a public food API.

Concepts: API integration, async data fetching, dynamic UI rendering.

Day 11 : User Profile Card Generator

Generates a user profile card dynamically from form inputs.

Concepts: User input processing, live UI generation, state-based rendering.