How to Implement a Weather App with External API Integration

You can implement a weather app with external API integration by using the browser's Fetch API to call OpenWeatherMap endpoints, parsing the JSON response for temperature and conditions, and dynamically injecting formatted HTML into the DOM using vanilla JavaScript.

This guide walks through a minimal yet complete implementation of a weather application using only HTML, CSS, and vanilla JavaScript. According to the jisan-mia/dom-projects source code, you can build a fully functional weather app with external API integration by following a simple three-file architecture that handles user input, fetches live meteorological data, and renders responsive results without any frameworks.

Project Architecture and File Structure

The repository follows a clean separation of concerns with dedicated files for markup, styling, and logic. In projects/weather-app/index.html, you'll find the search form and result container. The visual design lives in projects/weather-app/style.css, featuring gradient backgrounds and responsive layouts. Finally, projects/weather-app/script.js contains the core integration logic that communicates with the external weather service.

The data flow works as follows:

  • User Input: The visitor types a city name into the search field and clicks the Search button
  • API Request: JavaScript intercepts the form submission and constructs a request to the OpenWeatherMap API
  • Response Processing: The script checks the response code, extracts temperature, location name, and weather conditions
  • DOM Injection: Template literals build HTML markup that is injected into the result container, updating the page instantly without a reload

Setting Up the HTML Foundation

The markup provides a minimal interface with an input field for city names and a placeholder div where JavaScript will render the weather data. The structure intentionally avoids complexity to focus on the API integration logic.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="style.css" />
  <title>Weather App | DOM Projects</title>
</head>
<body>
  <main>
    <section class="main-section">
      <div class="search-div">
        <div class="title"><h1>Current Weather Condition</h1></div>
        <form>
          <div class="form-group">
            <input id="searchInput" placeholder="Search by your city name" type="text"
                   autocomplete="off" spellcheck="false" />
            <button id="submit-btn" class="submit-btn">Search</button>
          </div>
        </form>
      </div>

      <div id="result-div" class="result-div"></div>
    </section>
  </main>

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

This structure lives in projects/weather-app/index.html and provides the semantic foundation for the application.

Fetching Weather Data with JavaScript

The core API integration happens in projects/weather-app/script.js, where the Fetch API constructs a request URL with the city name, units preference, and API key.

// Grab the input field once
const searchInput = document.getElementById('searchInput');

// Click handler for the Search button
document.getElementById('submit-btn').addEventListener('click', e => {
  e.preventDefault();                 // Stop form submission
  const city = searchInput.value.trim();

  if (!city) {
    alert('Please enter your city name');
    return;
  }

  // Replace the hard-coded key with your own or a proxy endpoint
  const apiKey = '30c57aaa31356639f82849e3808f9f81';
  const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}`;

  fetch(url)
    .then(r => r.json())
    .then(data => {
      renderWeather(data);
      searchInput.value = '';
    })
    .catch(err => console.error('Fetch error:', err));
});

The endpoint https://api.openweathermap.org/data/2.5/weather accepts query parameters for the city name (q), unit system (units=metric), and authentication (appid). The script uses e.preventDefault() to stop the form from submitting traditionally, enabling asynchronous data fetching instead.

Rendering Results to the DOM

Once the API returns data, the renderWeather function validates the response and constructs the display markup. If the cod property equals 404, the function alerts the user that the city was not found.

function renderWeather(data) {
  if (data.cod === 404) {
    alert('404, City not found');
    return;
  }

  const { temp } = data.main;
  const location = data.name;
  const condition = data.weather[0].main;
  const icon = data.weather[0].icon;

  const html = `
    <div class="result-div-inner">
      <img src="https://openweathermap.org/img/wn/${icon}@2x.png" alt="${condition}" />
    </div>
    <div class="result-div-inner"><h2>${location}</h2></div>
    <div class="result-div-inner"><h3>${temp}<sup>°</sup> C</h3></div>
    <div class="result-div-inner"><h4>${condition}</h4></div>
  `;

  document.getElementById('result-div').innerHTML = html;
}

The function extracts data.main.temp for temperature, data.name for the location, and data.weather[0] for the condition description and icon ID. Using a template literal, it builds HTML with the OpenWeatherMap icon CDN URL and injects the complete string into the #result-div container via innerHTML.

Styling the Interface with CSS

The visual layer in projects/weather-app/style.css uses CSS gradients and flexbox to create a modern, responsive layout that works on mobile and desktop screens.

/* Gradient background for the search area */
.search-div {
  height: 240px;
  width: 100%;
  background-image: linear-gradient(to left, #00b4db, #0083b0);
}

/* Centered form on larger screens */
form {
  width: 400px;
  margin: 0 auto;
  text-align: center;
}

/* Result card with a top-to-bottom gradient */
.result-div {
  width: 100%;
  height: 423px;
  background-image: linear-gradient(to top, #2193b0, #6dd5ed);
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #fff;
}

/* Small-screen tweaks */
@media (max-width: 375px) {
  form { width: 350px; }
}

The stylesheet defines a gradient header for the search section and a contrasting gradient for the results area, using flexbox to center content vertically within the result container.

Security Considerations for Production

While the implementation in jisan-mia/dom-projects demonstrates the core integration pattern, several adjustments are necessary before deploying to production.

  • API Key Management: Storing the API key directly in script.js exposes it to anyone viewing the source code. Replace the hard-coded key with a server-side proxy or environment variable loaded at build time.
  • Error Handling: The current implementation only checks for 404 errors. Add handling for network failures, rate-limit responses (HTTP 429), and invalid API key errors (HTTP 401).
  • Code Modularization: As the app grows, move the fetch logic into a separate module (e.g., weatherService.js) and use ES modules (import/export) for better maintainability.

Summary

  • The weather app consists of three files: index.html for structure, style.css for presentation, and script.js for API integration logic.
  • OpenWeatherMap provides the meteorological data via a REST endpoint that accepts city names and returns JSON payloads containing temperature, conditions, and icon references.
  • The Fetch API handles the asynchronous request, while template literals and innerHTML enable instant UI updates without page reloads.
  • Production deployments require server-side API key storage and expanded error handling beyond the basic 404 check implemented in the source code.

Frequently Asked Questions

What external API does the weather app use?

The application integrates with the OpenWeatherMap API, specifically the /data/2.5/weather endpoint. This service returns current weather conditions, temperature data, and icon references for any valid city name passed as a query parameter.

How does the app display weather data without reloading the page?

The implementation uses the Fetch API to make asynchronous HTTP requests in the background. When the promise resolves, JavaScript parses the JSON response and updates the DOM directly using innerHTML, creating a single-page application experience where only the content within the result container changes.

Is it safe to hardcode the API key in the JavaScript file?

No, storing the API key directly in client-side code is insecure for production environments because the key is visible to anyone who inspects the source. You should replace the hard-coded string with a server-side proxy endpoint that securely stores the key, or use environment variables during a build process to inject the key only at deployment time.

How does the app handle invalid city names?

The renderWeather function checks if data.cod === 404 immediately after receiving the API response. If this condition is true, the function triggers an alert notifying the user that the city was not found and returns early without attempting to render weather data. For production use, you should replace the generic alert with a more user-friendly inline error message.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →