<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: hanna cantero</title>
    <description>The latest articles on DEV Community by hanna cantero (@boss_jhanna).</description>
    <link>https://dev.to/boss_jhanna</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3083857%2Fdd877d16-477e-4956-831b-db256ea83881.jpg</url>
      <title>DEV Community: hanna cantero</title>
      <link>https://dev.to/boss_jhanna</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/boss_jhanna"/>
    <language>en</language>
    <item>
      <title>Building a Weather App with OpenWeatherMap API and Vanilla JavaScript - A Perfect API Project for Beginners</title>
      <dc:creator>hanna cantero</dc:creator>
      <pubDate>Thu, 24 Apr 2025 14:41:17 +0000</pubDate>
      <link>https://dev.to/up_min_sparcs/building-a-weather-app-with-openweathermap-api-and-vanilla-javascript-a-perfect-api-project-for-2f99</link>
      <guid>https://dev.to/up_min_sparcs/building-a-weather-app-with-openweathermap-api-and-vanilla-javascript-a-perfect-api-project-for-2f99</guid>
      <description>&lt;p&gt;This article was co-authored by &lt;a class="mentioned-user" href="https://dev.to/notsol"&gt;@notsol&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Did you ever wonder how those weather apps work behind the scenes? Well, in this tutorial, you’ll learn how to build a clean and simple &lt;strong&gt;Weather Dashboard&lt;/strong&gt; called &lt;strong&gt;Lil’ Forecast&lt;/strong&gt; using nothing but &lt;strong&gt;HTML&lt;/strong&gt;, &lt;strong&gt;Vanilla JavaScript&lt;/strong&gt; (yupp, no complex JS frameworks here), and the &lt;strong&gt;OpenWeatherMap API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You’ll be able to search for any city in the world and instantly see its current weather — temperature, humidity, conditions, and even a neat little icon to match the vibe.&lt;/p&gt;

&lt;p&gt;At the end you will not only have a working Weather App, but you’ll also learn how to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect to external APIs using &lt;code&gt;fetch()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Parse and display real-time data&lt;/li&gt;
&lt;li&gt;Handle errors gracefully&lt;/li&gt;
&lt;li&gt;Build something lightweight and useful from scratch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s get started—and turn your browser into your personal weather station.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along, you’ll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of JavaScript and HTML&lt;/li&gt;
&lt;li&gt;A free API key from OpenWeatherMap&lt;/li&gt;
&lt;li&gt;A code editor (like VS Code) and a browse&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Start by creating the project directory and setting up your base files. &lt;br&gt;
Run these commands &lt;em&gt;&lt;u&gt;one by one&lt;/u&gt;&lt;/em&gt; in the Command Prompt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir lil-forecast
cd lil-forecast
type nul &amp;gt; index.html
type nul &amp;gt; script.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here’s what each command does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mkdir lil-forecast&lt;/code&gt; – creates a new folder named lil-forecast&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cd lil-forecast&lt;/code&gt; – moves into that folder&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;type nul &amp;gt; file_name&lt;/code&gt; – creates new empty file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, you have the essential files to start your weather app project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Your OpenWeatherMap API Key
&lt;/h2&gt;

&lt;p&gt;Here’s the breakdown process before you integrate the API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get your API key by signing up at OpenWeatherMap.&lt;/li&gt;
&lt;li&gt;After logging in, click your username on the upper right corner and select My API keys. The API key should look like this:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2e2vaxc9v1ehfjjvk2fy.png" alt="Image description" width="800" height="181"&gt;
&lt;/li&gt;
&lt;li&gt;It may take some time for the API key to activate. Take note that you &lt;em&gt;&lt;strong&gt;should never expose your API keys&lt;/strong&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;You can use API testing softwares like Postman to check if your API key is working. You may refer to this youtube link for a tutorial on how to check if the API key is working properly &lt;a href="https://www.youtube.com/watch?v=MdIfZJ08g2I&amp;amp;ab_channel=Andy%27sTechTutorials" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=MdIfZJ08g2I&amp;amp;ab_channel=Andy%27sTechTutorials&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Copy the API key and paste it in your JavaScript code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building HTML Structure
&lt;/h2&gt;

&lt;p&gt;Create a simple and intuitive layout that will include the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A text input to enter a city name&lt;/li&gt;
&lt;li&gt;A search button&lt;/li&gt;
&lt;li&gt;A section to display the weather information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can create your own HTML Structure or use the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta charset="UTF-8"&amp;gt;
        &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
        &amp;lt;title&amp;gt;Lil' Forecast&amp;lt;/title&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;form class="form"&amp;gt;
            &amp;lt;label for="city-input"&amp;gt;Enter city name&amp;lt;/label&amp;gt;
            &amp;lt;input type="text" id="city-input" placeholder="Enter city name" required&amp;gt;
            &amp;lt;button type="submit" id="search-button"&amp;gt;Search&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;

        &amp;lt;div&amp;gt;
            &amp;lt;h1 class="name"&amp;gt;&amp;lt;/h1&amp;gt;
            &amp;lt;h4 class="temp"&amp;gt;&amp;lt;/h4&amp;gt;
            &amp;lt;h4 class="humidity"&amp;gt;&amp;lt;/h4&amp;gt;
            &amp;lt;h4 class="description"&amp;gt;&amp;lt;/h4&amp;gt;
            &amp;lt;img class="icon"&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;script src="script.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Styling with CSS
&lt;/h2&gt;

&lt;p&gt;To make your weather app look visually appealing, you can style it with your own custom CSS to match your personal design tastes. Just create another file (style.css) and start adding styles — you have full control over colors, fonts, spacing, layout, and more.&lt;/p&gt;

&lt;p&gt;However, if you want a little head start, you can include a CSS framework like Bootstrap. This will help you make your weather app look clean and responsive without writing a lot of custom CSS from scratch.&lt;/p&gt;

&lt;p&gt;Here’s a quick example of how you could link your stylesheet in the HTML file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css" 
      rel="stylesheet" 
      integrity="sha384-SgOJa3DmI69IUzQ2PVdRZhwQ+dy64/BUtbMJw1MZ8t5HZApcHrRKUc4W0kG879m7" 
      crossorigin="anonymous"
&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Tip&lt;/em&gt;&lt;/strong&gt;: Keep your styles simple and build up as you go — start with the basic and necessary style.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript: Connecting to OpenWeatherMap API
&lt;/h2&gt;

&lt;p&gt;Now that your HTML layout is ready, it is time to bring the Weather Dashboard to life with JavaScript. You’ll walk through the process on how to fetch weather data from OpenWeatherMap and display it on the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;Selecting HTML Elements&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Start by selecting the elements from the HTML document that you’ll interact with using JavaScript. These will let you capture user input and update the page with the results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const form = document.querySelector('.form');
const input = document.getElementById('city-input');
const display = document.querySelector('.display');
const apiKey = '';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: &lt;em&gt;Handle the Form Submission&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Now, set up a listener for when the user submits the form (either by clicking the button or pressing Enter)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;form.addEventListener('submit', async e =&amp;gt; { // search button function
    e.preventDefault(); // preventing from refreshing the page

    input.classList.remove('is-invalid');
    form.classList.add('was-validated');

    if (!form.checkValidity()) {
        return; // return if input is empty don't execute
    }

    const cityName = input.value;

    try {
        const data = await getData(cityName);
        displayWeather(data);
        display.classList.remove('d-none');
    } catch (error) {
        console.error(error);
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What You’re Doing Here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevent the default form behavior (which would normally refresh the page)&lt;/li&gt;
&lt;li&gt;Validates the input field&lt;/li&gt;
&lt;li&gt;Fetches weather data for the city the user entered by calling the custom function&lt;/li&gt;
&lt;li&gt;Displays the weather information if the request succeeds&lt;/li&gt;
&lt;li&gt;Handles errors gracefully&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: &lt;em&gt;Fetch Weather Data from the API&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Next, write a function to connect to the OpenWeatherMap API and get the weather for the city the user entered.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function getData(cityName) { // sends a http request to the API
    const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&amp;amp;appid=${apiKey}`

    const apiResponse = await fetch(apiUrl);

    if (!apiResponse.ok) { // check if api response ok is false
        form.classList.remove('was-validated');
        input.classList.add('is-invalid');
        throw new Error('Could not fetch weather data');
    }

    return await apiResponse.json();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here’s What’s Happening:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You build the API URL using the city name and the API key&lt;/li&gt;
&lt;li&gt;Then, by the use of &lt;code&gt;fetch()&lt;/code&gt; to request weather data from the server&lt;/li&gt;
&lt;li&gt;If the response indicates a problem/error (like “city not found”), you manually throw an error.&lt;/li&gt;
&lt;li&gt;If the request is successful, the function will return the weather data in JSON format.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: &lt;em&gt;Display the Weather on the Page&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Once the weather data is obtained, it is time to show it to the user by updating the content of the display section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function displayWeather(data) { // displays the weather data 
    const nameDisplay = document.querySelector('.name');
    const tempDisplay = document.querySelector('.temp');
    const humidityDisplay = document.querySelector('.humidity');
    const descriptionDisplay = document.querySelector('.description');
    const iconDisplay = document.querySelector('.icon');

    const {name: cityName, main: {temp, humidity}, weather: [{description, icon}]} = data; // destructuring the data from the json file

    nameDisplay.innerHTML = cityName;
    tempDisplay.innerHTML = `Temperature: ${Math.round((temp - 273.15) * 100) / 100}°C`;
    humidityDisplay.innerHTML = `Humidity: ${humidity}%`;
    descriptionDisplay.innerHTML = `Description: ${description}`;
    iconDisplay.src = `https://openweathermap.org/img/wn/${icon}@2x.png`;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full Flow
&lt;/h2&gt;

&lt;p&gt;Here’s what your weather app now does: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Homepage&lt;/strong&gt; – when the Lil’ Forecast app loads, users are greeted with a simple interface: a title, an input, and a search button. No distractions—just type and go!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zuociigudlfpvdmvnkg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zuociigudlfpvdmvnkg.jpg" alt="Image description" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Searching a city&lt;/strong&gt; – the user types the name of any city in the world. In this example, “Davao” was typed to check the weather there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F030v4tnml6ccfjz4i8z0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F030v4tnml6ccfjz4i8z0.jpg" alt="Image description" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weather Data Displayed&lt;/strong&gt; – The app pulls real-time weather data from OpenWeatherMap and displays it beautifully: complete with temperature, humidity, description, and a matching weather icon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhwp5gz1au3q2jh0c3ki.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhwp5gz1au3q2jh0c3ki.jpg" alt="Image description" width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;And just like that, you’ve built a fully functional weather dashboard from scratch using nothing but HTML, Vanilla JavaScript, and the OpenWeatherMap API.&lt;/p&gt;

&lt;p&gt;With Lil’ Forecast, you’ve learned how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Capture user input and validate it&lt;/li&gt;
&lt;li&gt;Fetch real-time weather data from a public API&lt;/li&gt;
&lt;li&gt;Dynamically update your UI with real-time information&lt;/li&gt;
&lt;li&gt;Handle errors in a clean and user-friendly way&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More significantly, you’ve now seen what it’s like to create a real-time API-driven application — no complex frameworks, no bloat — just you and the underlying web technologies.&lt;/p&gt;

&lt;p&gt;This is just the beginning, you can still take your weather app (or any app) even further, with the knowledge of bringing live data into your app, the browser is yours to explore. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;So yeah… keep building, keep learning!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://openweathermap.org/current" rel="noopener noreferrer"&gt;https://openweathermap.org/current&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/VaDUGPMjzOM?si=t2GG5zm51joGQHCh" rel="noopener noreferrer"&gt;https://youtu.be/VaDUGPMjzOM?si=t2GG5zm51joGQHCh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=MdIfZJ08g2I&amp;amp;ab_channel=Andy%27sTechTutorials" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=MdIfZJ08g2I&amp;amp;ab_channel=Andy%27sTechTutorials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;br&gt;
&lt;a href="https://github.com/not-sol/open-weather-map/tree/main" rel="noopener noreferrer"&gt;https://github.com/not-sol/open-weather-map/tree/main&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>api</category>
    </item>
  </channel>
</rss>
