Search Cities by Air Quality
Find real-time air quality data for any city worldwide. Search by name or browse by state to get instant AQI information.
Find Any City's Air Quality
Type any city name to see real-time air quality data
Popular Cities
Quick access to frequently searched cities with real-time AQI data
Loading real-time AQI data...
`;
// Add popular suggestions
const popularSuggestions = [
'Los Angeles', 'New York', 'Chicago', 'San Francisco', 'Miami', 'Seattle',
'Boston', 'Denver', 'Houston', 'Dallas', 'Atlanta', 'Phoenix',
'Philadelphia', 'San Diego', 'Portland', 'Austin', 'Nashville', 'Orlando',
'London', 'Paris', 'Tokyo', 'Beijing', 'Shanghai', 'Mumbai', 'Delhi',
'Singapore', 'Hong Kong', 'Sydney', 'Melbourne', 'Toronto', 'Vancouver',
'Mexico City', 'São Paulo', 'Buenos Aires', 'Lima', 'Dubai', 'Cairo'
];
const matchingSuggestions = popularSuggestions.filter(city =>
city.toLowerCase().includes(query.toLowerCase())
);
matchingSuggestions.forEach(city => {
const citySlug = city.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-');
suggestionsHTML += `
${city}
`;
});
suggestionsBox.innerHTML = suggestionsHTML;
suggestionsBox.style.display = 'block';
}
function hideSuggestions() {
suggestionsBox.style.display = 'none';
}
// Hide suggestions when clicking outside
document.addEventListener('click', function(e) {
if (!e.target.closest('.search-input-wrapper')) {
hideSuggestions();
}
});
// Load popular cities with real-time AQI
loadPopularCities();
}); function loadPopularCities() {
const popularCities = [
{ name: 'Los Angeles', slug: 'los-angeles', lat: 34.0522, lon: -118.2437 },
{ name: 'New York', slug: 'new-york', lat: 40.7128, lon: -74.0060 },
{ name: 'Chicago', slug: 'chicago', lat: 41.8781, lon: -87.6298 },
{ name: 'San Francisco', slug: 'san-francisco', lat: 37.7749, lon: -122.4194 },
{ name: 'Miami', slug: 'miami', lat: 25.7617, lon: -80.1918 },
{ name: 'Seattle', slug: 'seattle', lat: 47.6062, lon: -122.3321 },
{ name: 'Boston', slug: 'boston', lat: 42.3601, lon: -71.0589 },
{ name: 'Denver', slug: 'denver', lat: 39.7392, lon: -104.9903 },
{ name: 'Houston', slug: 'houston', lat: 29.7604, lon: -95.3698 },
{ name: 'Phoenix', slug: 'phoenix', lat: 33.4484, lon: -112.0740 },
{ name: 'Philadelphia', slug: 'philadelphia', lat: 39.9526, lon: -75.1652 },
{ name: 'San Diego', slug: 'san-diego', lat: 32.7157, lon: -117.1611 },
{ name: 'Dallas', slug: 'dallas', lat: 32.7767, lon: -96.7970 },
{ name: 'Atlanta', slug: 'atlanta', lat: 33.7490, lon: -84.3880 },
{ name: 'Portland', slug: 'portland', lat: 45.5152, lon: -122.6784 },
{ name: 'Austin', slug: 'austin', lat: 30.2672, lon: -97.7431 },
{ name: 'Las Vegas', slug: 'las-vegas', lat: 36.1699, lon: -115.1398 },
{ name: 'Nashville', slug: 'nashville', lat: 36.1627, lon: -86.7816 },
{ name: 'Detroit', slug: 'detroit', lat: 42.3314, lon: -83.0458 },
{ name: 'Minneapolis', slug: 'minneapolis', lat: 44.9778, lon: -93.2650 },
{ name: 'London', slug: 'london', lat: 51.5074, lon: -0.1278 },
{ name: 'Paris', slug: 'paris', lat: 48.8566, lon: 2.3522 },
{ name: 'Tokyo', slug: 'tokyo', lat: 35.6762, lon: 139.6503 },
{ name: 'Beijing', slug: 'beijing', lat: 39.9042, lon: 116.4074 },
{ name: 'Singapore', slug: 'singapore', lat: 1.3521, lon: 103.8198 },
{ name: 'Sydney', slug: 'sydney', lat: -33.8688, lon: 151.2093 },
{ name: 'Toronto', slug: 'toronto', lat: 43.6532, lon: -79.3832 },
{ name: 'Dubai', slug: 'dubai', lat: 25.2048, lon: 55.2708 },
{ name: 'Mexico City', slug: 'mexico-city', lat: 19.4326, lon: -99.1332 },
{ name: 'Buenos Aires', slug: 'buenos-aires', lat: -34.6037, lon: -58.3816 }
];
const grid = document.getElementById('popularCitiesGrid');
// EPA PM2.5 to AQI conversion
function calculateAQI(pm25) {
const breakpoints = [
{ low: 0.0, high: 12.0, aqiLow: 0, aqiHigh: 50 },
{ low: 12.1, high: 35.4, aqiLow: 51, aqiHigh: 100 },
{ low: 35.5, high: 55.4, aqiLow: 101, aqiHigh: 150 },
{ low: 55.5, high: 150.4, aqiLow: 151, aqiHigh: 200 },
{ low: 150.5, high: 250.4, aqiLow: 201, aqiHigh: 300 },
{ low: 250.5, high: 500.4, aqiLow: 301, aqiHigh: 500 }
];
for (let bp of breakpoints) {
if (pm25 >= bp.low && pm25 500.4 ? 500 : 0;
}
function getAQIColor(aqi) {
if (aqi {
citiesHTML += `
${city.name}
Loading...
`;
});
grid.innerHTML = citiesHTML;
// Load real-time AQI for each city
citiesToShow.forEach(city => {
// Create proper AJAX URL with nonce
const ajaxUrl = 'https://cleanairinitiative.org/wp-admin/admin-ajax.php';
const nonce = '2607d0254f';
fetch(`${ajaxUrl}?action=get_openweather_data&endpoint=air_quality¶ms[lat]=${city.lat}¶ms[lon]=${city.lon}&security=${nonce}`)
.then(response => response.json())
.then(data => {
if (data.success && data.data && data.data.list && data.data.list[0]) {
const pm25 = data.data.list[0].components.pm2_5 || 0;
const aqi = calculateAQI(pm25);
const color = getAQIColor(aqi);
const cityCardBadge = document.querySelector(`[data-city="${city.slug}"] .city-aqi-badge`);
const cityCardStatus = document.querySelector(`[data-city="${city.slug}"] .city-aqi-status`);
if (cityCardBadge) {
cityCardBadge.innerHTML = `
${aqi}`;
cityCardBadge.style.background = color;
cityCardBadge.style.color = 'white';
}
if (cityCardStatus) {
let status = 'Good';
if (aqi > 50) status = 'Moderate';
if (aqi > 100) status = 'Unhealthy for Sensitive';
if (aqi > 150) status = 'Unhealthy';
if (aqi > 200) status = 'Very Unhealthy';
if (aqi > 300) status = 'Hazardous';
cityCardStatus.textContent = status;
}
}
})
.catch(error => {
console.error('Error loading AQI for', city.name, error);
const cityCardBadge = document.querySelector(`[data-city="${city.slug}"] .city-aqi-badge`);
const cityCardStatus = document.querySelector(`[data-city="${city.slug}"] .city-aqi-status`);
if (cityCardBadge) {
cityCardBadge.innerHTML = '
—';
cityCardBadge.style.background = '#ccc';
cityCardBadge.style.color = 'white';
}
if (cityCardStatus) {
cityCardStatus.textContent = 'Unavailable';
}
});
});
}