How to Render a Weather Widget as an Image

Render a weather widget as a PNG. Useful for digital signage, daily-briefing emails and weather-app share cards.

HTML Content

<div class="weather-widget">
    <div class="current-weather">
        <div class="weather-icon">
            <svg viewBox="0 0 24 24" width="64" height="64">
                <path fill="currentColor" d="M12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,2L14.39,5.42C13.65,5.15 12.84,5 12,5C11.16,5 10.35,5.15 9.61,5.42L12,2M3.34,7L7.5,6.65C6.9,7.16 6.36,7.78 5.94,8.5C5.5,9.24 5.25,10 5.11,10.79L3.34,7M3.36,17L5.12,13.23C5.26,14 5.53,14.78 5.95,15.5C6.37,16.24 6.91,16.86 7.5,17.37L3.36,17M20.65,7L18.88,10.79C18.74,10 18.47,9.23 18.05,8.5C17.63,7.78 17.1,7.15 16.5,6.64L20.65,7M20.64,17L16.5,17.36C17.09,16.85 17.62,16.22 18.04,15.5C18.46,14.77 18.73,14 18.87,13.21L20.64,17M12,22L9.59,18.56C10.33,18.83 11.14,19 12,19C12.82,19 13.63,18.83 14.37,18.56L12,22Z" />
            </svg>
        </div>
        <div class="temp-info">
            <div class="temperature">28°C</div>
            <div class="description">Sunny</div>
        </div>
    </div>
    <div class="weather-details">
        <div class="detail">
            <div class="label">Humidity</div>
            <div class="value">65%</div>
        </div>
        <div class="detail">
            <div class="label">Wind</div>
            <div class="value">12 km/h</div>
        </div>
        <div class="detail">
            <div class="label">UV Index</div>
            <div class="value">6</div>
        </div>
    </div>
    <div class="location">
        <svg viewBox="0 0 24 24" width="16" height="16">
            <path fill="currentColor" d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z" />
        </svg>
        <span>San Francisco, CA</span>
    </div>
    <div class="forecast">
        <div class="forecast-item">
            <div class="day">MON</div>
            <div class="icon">☀️</div>
            <div class="temp">29°</div>
        </div>
        <div class="forecast-item">
            <div class="day">TUE</div>
            <div class="icon">⛅</div>
            <div class="temp">27°</div>
        </div>
        <div class="forecast-item">
            <div class="day">WED</div>
            <div class="icon">🌤️</div>
            <div class="temp">28°</div>
        </div>
        <div class="forecast-item">
            <div class="day">THU</div>
            <div class="icon">🌥️</div>
            <div class="temp">26°</div>
        </div>
    </div>
</div>

CSS Styles

body {
    margin: 0;
    padding: 24px;
    background: white;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

.weather-widget {
    width: 300px;
    background: linear-gradient(135deg, #4c6ef5, #228be6);
    color: white;
    border-radius: 16px;
    padding: 24px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.1);
}

.current-weather {
    display: flex;
    align-items: center;
    margin-bottom: 24px;
}

.weather-icon {
    margin-right: 16px;
}

.temperature {
    font-size: 48px;
    font-weight: 700;
    line-height: 1;
    margin-bottom: 4px;
}

.description {
    font-size: 16px;
    opacity: 0.9;
}

.weather-details {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    padding: 16px 0;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    margin-bottom: 16px;
}

.detail {
    text-align: center;
}

.label {
    font-size: 12px;
    opacity: 0.8;
    margin-bottom: 4px;
}

.value {
    font-size: 16px;
    font-weight: 600;
}

.location {
    display: flex;
    align-items: center;
    font-size: 14px;
    opacity: 0.9;
    margin-bottom: 24px;
}

.location svg {
    margin-right: 6px;
}

.forecast {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
}

.forecast-item {
    text-align: center;
    font-size: 14px;
}

.day {
    opacity: 0.8;
    margin-bottom: 4px;
}

.icon {
    font-size: 20px;
    margin: 4px 0;
}

.temp {
    font-weight: 600;
}

API Request

POST https://app.html2img.com/api/html
{
    "html": "<div class=\"weather-widget\"><div class=\"current-weather\"><div class=\"weather-icon\"><svg viewBox=\"0 0 24 24\" width=\"64\" height=\"64\"><path fill=\"currentColor\" d=\"M12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,2L14.39,5.42C13.65,5.15 12.84,5 12,5C11.16,5 10.35,5.15 9.61,5.42L12,2M3.34,7L7.5,6.65C6.9,7.16 6.36,7.78 5.94,8.5C5.5,9.24 5.25,10 5.11,10.79L3.34,7M3.36,17L5.12,13.23C5.26,14 5.53,14.78 5.95,15.5C6.37,16.24 6.91,16.86 7.5,17.37L3.36,17M20.65,7L18.88,10.79C18.74,10 18.47,9.23 18.05,8.5C17.63,7.78 17.1,7.15 16.5,6.64L20.65,7M20.64,17L16.5,17.36C17.09,16.85 17.62,16.22 18.04,15.5C18.46,14.77 18.73,14 18.87,13.21L20.64,17M12,22L9.59,18.56C10.33,18.83 11.14,19 12,19C12.82,19 13.63,18.83 14.37,18.56L12,22Z\" /></svg></div><div class=\"temp-info\"><div class=\"temperature\">28°C</div><div class=\"description\">Sunny</div></div></div><div class=\"weather-details\"><div class=\"detail\"><div class=\"label\">Humidity</div><div class=\"value\">65%</div></div><div class=\"detail\"><div class=\"label\">Wind</div><div class=\"value\">12 km/h</div></div><div class=\"detail\"><div class=\"label\">UV Index</div><div class=\"value\">6</div></div></div><div class=\"location\"><svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\"><path fill=\"currentColor\" d=\"M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z\" /></svg><span>San Francisco, CA</span></div><div class=\"forecast\"><div class=\"forecast-item\"><div class=\"day\">MON</div><div class=\"icon\">☀️</div><div class=\"temp\">29°</div></div><div class=\"forecast-item\"><div class=\"day\">TUE</div><div class=\"icon\">⛅</div><div class=\"temp\">27°</div></div><div class=\"forecast-item\"><div class=\"day\">WED</div><div class=\"icon\">🌤️</div><div class=\"temp\">28°</div></div><div class=\"forecast-item\"><div class=\"day\">THU</div><div class=\"icon\">🌥️</div><div class=\"temp\">26°</div></div></div></div>",
    "width": 348,
    "height": 355,
    "css": "body{margin:0;padding:0;background:white;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif}.weather-widget{width:300px;background:linear-gradient(135deg,#4c6ef5,#228be6);color:white;border-radius:16px;padding:24px;box-shadow:0 4px 24px rgba(0,0,0,0.1)}.current-weather{display:flex;align-items:center;margin-bottom:24px}.weather-icon{margin-right:16px}.temperature{font-size:48px;font-weight:700;line-height:1;margin-bottom:4px}.description{font-size:16px;opacity:0.9}.weather-details{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;padding:16px 0;border-top:1px solid rgba(255,255,255,0.1);border-bottom:1px solid rgba(255,255,255,0.1);margin-bottom:16px}.detail{text-align:center}.label{font-size:12px;opacity:0.8;margin-bottom:4px}.value{font-size:16px;font-weight:600}.location{display:flex;align-items:center;font-size:14px;opacity:0.9;margin-bottom:24px}.location svg{margin-right:6px}.forecast{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.forecast-item{text-align:center;font-size:14px}.day{opacity:0.8;margin-bottom:4px}.icon{font-size:20px;margin:4px 0}.temp{font-weight:600}"
}
Weather Widget Example

Update the weather data, location, and forecast information to match your needs.

How it Works

  1. Modern gradient background with weather information
  2. SVG icons for weather conditions
  3. Grid layout for weather details and forecast
  4. Responsive design that works well on any device

The widget uses emoji for forecast icons which may render differently across platforms. Use SVG icons for consistent results.

Code in other languages

Node.js

const response = await fetch('https://app.html2img.com/api/html', {
  method: 'POST',
  headers: { 'X-API-Key': process.env.HTML2IMG_API_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ html: weatherHtml, css: weatherCss, width: 600, height: 400 }),
});
const { url } = await response.json();

Python

import os, requests
response = requests.post(
    'https://app.html2img.com/api/html',
    headers={'X-API-Key': os.environ['HTML2IMG_API_KEY']},
    json={'html': weather_html, 'css': weather_css, 'width': 600, 'height': 400},
)
url = response.json()['url']

PHP

$ch = curl_init('https://app.html2img.com/api/html');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('HTML2IMG_API_KEY'), 'Content-Type: application/json'],
    CURLOPT_POSTFIELDS => json_encode(['html' => $weatherHtml, 'css' => $weatherCss, 'width' => 600, 'height' => 400]),
]);
$url = json_decode(curl_exec($ch), true)['url'];

Common pitfalls

  • Emoji icons render inconsistently. Replace emoji with self-hosted SVGs so the widget looks the same in every render.
  • Temperature unit drift. Always include the unit in the rendered string (“72F” or “22C”) so the image is unambiguous.
  • Long city names overflow. Use text-overflow: ellipsis on the location label or pre-truncate in your data layer.

See also