Step-by-step guide to build modern weather application with Lovable, including API integrations, code examples, responsive design, deployment tips

Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
A minimal, production-ready Weather app in Lovable is best built as a client-side React app that calls a no-key public API (Open‑Meteo) so you can implement and preview entirely inside Lovable (no terminal). I’ll give you step-by-step Lovable chat prompts to create files, wire UI, and optionally add a Supabase favorites feature (that part uses Lovable’s Integrations/Secrets UI). Paste each prompt into Lovable Chat Mode and use Preview → Publish.
Single-page Weather app where a user types a city, the app geocodes the city (open API), fetches current temperature and conditions from Open‑Meteo, and shows a small WeatherCard. Optional: save favorite cities to Supabase.
Use Chat Mode edits to create files and modify src/App.tsx. Use Preview to run and test. Use Lovable Cloud Secrets UI only if you add Supabase. Publish from the Lovable Publish button. No CLI required. If you want a secure backend proxy for API keys, export to GitHub and deploy externally — I indicate if that’s needed.
Prompt 1: Create core UI and fetch logic
Goal: Add a simple UI and weather-fetching module that uses Open‑Meteo (no API key).
Files to create/modify:
// Create src/lib/weather.ts
// Implement a function fetchCurrentWeather(lat, lon) that calls https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}¤t_weather=true
// Return the current_weather object.
// Create src/components/WeatherCard.tsx
// A presentational React component that accepts props: {city, tempC, wind, time} and renders them nicely.
// Update src/App.tsx
// Replace the root UI with:
// - text input to enter city
// - Search button that calls geocodeCity then fetchCurrentWeather and renders WeatherCard
// Include basic loading and error states.
Prompt 2: Improve UX and caching
Goal: Add simple localStorage caching for last-searched city and results.
Files to modify:
- update src/App.tsx (add localStorage load/save and show last city on mount)
Acceptance criteria: Done when a search persists across Preview reloads in the Lovable Preview tab.
Any needed Secrets/integration steps: None.
Prompt content to paste:
// Update src/App.tsx
// On mount, read localStorage.lastWeather and prefill UI if present.
// After successful fetch, save lastWeather = JSON.stringify({city, result})
// Ensure loading/error states remain correct.
Prompt 3 (optional): Add Supabase favorites (requires Lovable Integrations & Secrets)
Goal: Let signed-in users save favorite cities to Supabase and list them.
Files to create/modify:
- create src/lib/supabaseClient.ts
- update src/App.tsx (add Save Favorite button and list)
Acceptance criteria: Done when Save Favorite writes to Supabase and list displays rows from the favorites table.
Any needed Secrets/integration steps:
- In Lovable Cloud, open Secrets UI and add SUPABASE_URL and SUPABASE_ANON\_KEY.
- Create a Supabase table "favorites" with columns: id (uuid), city (text), lat (numeric), lon (numeric), created\_at (timestamp).
Prompt content to paste:
// Create src/lib/supabaseClient.ts
// Initialize supabase-js using environment variables: SUPABASE_URL, SUPABASE_ANON_KEY (read from process.env or the platform-specific env access).
// Provide helper functions: addFavorite({city, lat, lon}) and listFavorites().
// Update src/App.tsx
// Add "Save Favorite" button that calls addFavorite with current city coords.
// Add a Favorites list UI that calls listFavorites on mount and after save.
<h3>How to verify in Lovable Preview</h3>
<ul>
<li><b>Type a city name</b> (e.g., "Berlin") and click Search — Preview should show temperature, time, and wind.</li>
<li><b>Reload Preview</b> to confirm last-search persisted if you added caching.</li>
<li><b>If Supabase enabled</b>, click Save Favorite and confirm the favorites list updates.</li>
</ul>
<h3>How to Publish / re-publish</h3>
<ul>
<li><b>Use Lovable Publish button</b> to publish changes. Preview reflects edits; Publish makes them live on your Lovable site.</li>
<li><b>If you added Supabase</b>, ensure Secrets are set in Lovable Cloud before Publish so the live site can access them.</li>
</ul>
<h3>Common pitfalls in Lovable (and how to avoid them)</h3>
<ul>
<li><b>Assuming CLI is available:</b> Don’t expect to run npm installs in Lovable. Use browser-friendly libs and CDNs where possible.</li>
<li><b>API keys in client code:</b> Avoid embedding secret API keys client-side. Use public no-key APIs like Open‑Meteo or wire up a secure backend outside Lovable (GitHub export + external deploy) if you need secrets not suitable for client exposure.</li>
<li><b>Secrets visibility:</b> If you use Supabase, set keys via Lovable Secrets UI before Publish; forgetting this causes runtime errors only in Preview/Live, not in Chat Mode edits.</li>
</ul>
<h3>Validity bar</h3>
<ul>
<li><b>Accurate to Lovable’s chat-first workflow:</b> All changes are made via Chat Mode edits, Preview, Secrets UI, and Publish. No terminal steps required.</li>
<li><b>If you need a secure backend or custom build steps:</b> I’ll label them as "outside Lovable (terminal required)" and recommend GitHub export/sync.</li>
</ul>
This prompt helps an AI assistant understand your setup and guide to build the feature
This prompt helps an AI assistant understand your setup and guide to build the feature
This prompt helps an AI assistant understand your setup and guide to build the feature

Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Use AI code generators inside Lovable to scaffold the UI and API quickly, but treat the generated output as a starting point: secure API keys with Lovable Secrets, implement a server-side proxy (serverless API route) so keys never go to the browser, add caching and rate-limit handling, validate inputs, review and edit generated diffs in Chat Mode, test in Preview, and export to GitHub for CI/tests when you need terminal-level control.
// serverless API route: /api/weather
// This keeps the OpenWeather API key on the server-side
import fetch from 'node-fetch'
// Simple in-memory cache (ephemeral in serverless)
const cache = {}
export default async function handler(req, res) {
// // Validate input!
const q = (req.query.q || '').trim()
if (!q) return res.status(400).json({ error: 'Missing q (city or query)' })
// // Check cache
const key = `weather:${q.toLowerCase()}`
const now = Date.now()
const cached = cache[key]
if (cached && now - cached.ts < 60_000) return res.json(cached.data)
// // Use secret from environment; set it in Lovable Secrets UI as OPENWEATHER_API_KEY
const apiKey = process.env.OPENWEATHER_API_KEY
if (!apiKey) return res.status(500).json({ error: 'Server misconfigured' })
const url = `https://api.openweathermap.org/data/2.5/weather?q=${encodeURIComponent(q)}&appid=${apiKey}&units=metric`
const resp = await fetch(url)
if (!resp.ok) {
// // Propagate helpful errors (and handle rate limits)
const text = await resp.text()
return res.status(resp.status).json({ error: text })
}
const data = await resp.json()
cache[key] = { ts: now, data }
return res.json(data)
}
// client-side fetch example
// Call the serverless proxy so the API key is never exposed to the browser
async function getWeather(city) {
// // Basic input sanitation
const q = city.trim()
const res = await fetch(`/api/weather?q=${encodeURIComponent(q)}`)
if (!res.ok) {
// // handle errors gracefully in UI
const err = await res.json()
throw new Error(err.error || 'Unknown error')
}
return res.json()
}
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.