Geolocation: Weather application

Fetch weather data from an API using the user's geolocation data.

Last updated Apr 23, 2026 If you want to get started quickly, click on the button below.

Deploy to Cloudflare

This creates a repository in your GitHub account and deploys the application to Cloudflare Workers.

export default {
    async fetch(request) {
        let endpoint = "https://api.waqi.info/feed/geo:";
        const token = ""; //Use a token from https://aqicn.org/api/
        let html_style = `body{padding:6em; font-family: sans-serif;} h1{color:#f6821f}`;

        let html_content = "<h1>Weather 🌦</h1>";

        const latitude = request.cf.latitude;
        const longitude = request.cf.longitude;
        endpoint += `${latitude};${longitude}/?token=${token}`;
        const init = {
            headers: {
                "content-type": "application/json;charset=UTF-8",
            },
        };

        const response = await fetch(endpoint, init);
        const content = await response.json();

        html_content += `<p>This is a demo using Workers geolocation data. </p>`;
        html_content += `You are located at: ${latitude},${longitude}.</p>`;
        html_content += `<p>Based off sensor data from <a href="${content.data.city.url}">${content.data.city.name}</a>:</p>`;
        html_content += `<p>The AQI level is: ${content.data.aqi}.</p>`;
        html_content += `<p>The N02 level is: ${content.data.iaqi.no2?.v}.</p>`;
        html_content += `<p>The O3 level is: ${content.data.iaqi.o3?.v}.</p>`;
        html_content += `<p>The temperature is: ${content.data.iaqi.t?.v}°C.</p>`;

        let html = `
      <!DOCTYPE html>
      <head>
        <title>Geolocation: Weather</title>
      </head>
      <body>
        <style>${html_style}</style>
        <div id="container">
        ${html_content}
        </div>
      </body>`;

        return new Response(html, {
            headers: {
                "content-type": "text/html;charset=UTF-8",
            },
        });
    },
};
export default {
    async fetch(request): Promise<Response> {
        let endpoint = "https://api.waqi.info/feed/geo:";
        const token = ""; //Use a token from https://aqicn.org/api/
        let html_style = `body{padding:6em; font-family: sans-serif;} h1{color:#f6821f}`;

        let html_content = "<h1>Weather 🌦</h1>";

        const latitude = request.cf.latitude;
        const longitude = request.cf.longitude;
        endpoint += `${latitude};${longitude}/?token=${token}`;
        const init = {
            headers: {
                "content-type": "application/json;charset=UTF-8",
            },
        };

        const response = await fetch(endpoint, init);
        const content = await response.json();

        html_content += `<p>This is a demo using Workers geolocation data. </p>`;
        html_content += `You are located at: ${latitude},${longitude}.</p>`;
        html_content += `<p>Based off sensor data from <a href="${content.data.city.url}">${content.data.city.name}</a>:</p>`;
        html_content += `<p>The AQI level is: ${content.data.aqi}.</p>`;
        html_content += `<p>The N02 level is: ${content.data.iaqi.no2?.v}.</p>`;
        html_content += `<p>The O3 level is: ${content.data.iaqi.o3?.v}.</p>`;
        html_content += `<p>The temperature is: ${content.data.iaqi.t?.v}°C.</p>`;

        let html = `
      <!DOCTYPE html>
      <head>
        <title>Geolocation: Weather</title>
      </head>
      <body>
        <style>${html_style}</style>
        <div id="container">
        ${html_content}
        </div>
      </body>`;

        return new Response(html, {
            headers: {
                "content-type": "text/html;charset=UTF-8",
            },
        });
    },
} satisfies ExportedHandler;
import { Hono } from 'hono';
import { html } from 'hono/html';

type Bindings = {};

interface WeatherApiResponse {
  data: {
    aqi: number;
    city: {
      name: string;
      url: string;
    };
    iaqi: {
      no2?: { v: number };
      o3?: { v: number };
      t?: { v: number };
    };
  };
}

const app = new Hono<{ Bindings: Bindings }>();

app.get('*', async (c) => {
  // Get API endpoint
  let endpoint = "https://api.waqi.info/feed/geo:";
  const token = ""; // Use a token from https://aqicn.org/api/

  // Define styles
  const html_style = `body{padding:6em; font-family: sans-serif;} h1{color:#f6821f}`;

  // Get geolocation from Cloudflare request
  const req = c.req.raw;
  const latitude = req.cf?.latitude;
  const longitude = req.cf?.longitude;

  // Create complete API endpoint with coordinates
  endpoint += `${latitude};${longitude}/?token=${token}`;

  // Fetch weather data
  const init = {
    headers: {
      "content-type": "application/json;charset=UTF-8",
    },
  };
  const response = await fetch(endpoint, init);
  const content = await response.json() as WeatherApiResponse;

  // Build HTML content
  const weatherContent = html`
    <h1>Weather 🌦</h1>
    <p>This is a demo using Workers geolocation data.</p>
    <p>You are located at: ${latitude},${longitude}.</p>
    <p>Based off sensor data from <a href="${content.data.city.url}">${content.data.city.name}</a>:</p>
    <p>The AQI level is: ${content.data.aqi}.</p>
    <p>The N02 level is: ${content.data.iaqi.no2?.v}.</p>
    <p>The O3 level is: ${content.data.iaqi.o3?.v}.</p>
    <p>The temperature is: ${content.data.iaqi.t?.v}°C.</p>
  `;

  // Complete HTML document
  const htmlDocument = html`
    <!DOCTYPE html>
    <head>
      <title>Geolocation: Weather</title>
    </head>
    <body>
      <style>${html_style}</style>
      <div id="container">
        ${weatherContent}
      </div>
    </body>
  `;

  // Return HTML response
  return c.html(htmlDocument);
});

export default app;
from workers import WorkerEntrypoint, Response, fetch

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        endpoint = "https://api.waqi.info/feed/geo:"
        token = "" # Use a token from https://aqicn.org/api/
        html_style = "body{padding:6em; font-family: sans-serif;} h1{color:#f6821f}"
        html_content = "<h1>Weather 🌦</h1>"

        latitude = request.cf.latitude
        longitude = request.cf.longitude

        endpoint += f"{latitude};{longitude}/?token={token}"
        response = await fetch(endpoint)
        content = await response.json()

        html_content += "<p>This is a demo using Workers geolocation data. </p>"
        html_content += f"You are located at: {latitude},{longitude}.</p>"
        html_content += f"<p>Based off sensor data from <a href='{content['data']['city']['url']}'>{content['data']['city']['name']}</a>:</p>"
        html_content += f"<p>The AQI level is: {content['data']['aqi']}.</p>"
        html_content += f"<p>The N02 level is: {content['data']['iaqi']['no2']['v']}.</p>"
        html_content += f"<p>The O3 level is: {content['data']['iaqi']['o3']['v']}.</p>"
        html_content += f"<p>The temperature is: {content['data']['iaqi']['t']['v']}°C.</p>"

        html = f"""
        <!DOCTYPE html>
          <head>
            <title>Geolocation: Weather</title>
          </head>
          <body>
            <style>{html_style}</style>
            <div id="container">
            {html_content}
            </div>
          </body>
        """

        headers = {"content-type": "text/html;charset=UTF-8"}
        return Response(html, headers=headers)

Was this helpful?

YesNo

On this page

Geolocation: Weather application - 图2Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/workers/examples/geolocation-app-weather/#page","headline":"Geolocation: Weather application","description":"Fetch weather data from an API using the user's geolocation data.","url":"https://developers.cloudflare.com/workers/examples/geolocation-app-weather/","inLanguage":"en","image":"https://developers.cloudflare.com/workers/examples/geolocation-app-weather/og.png?v=972760bfcd66e48d","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Geolocation","JavaScript","TypeScript","Python"]}


description: Personalize website styling based on localized user time. title: "Geolocation: Custom Styling" image: https://developers.cloudflare.com/workers/examples/geolocation-custom-styling/og.png?v=6862e2c3f7438877


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/workers/llms.txt
Use this file to discover all available pages before exploring further.