Phone Weather Apps
Hz-Weather Pro has dedicated weather apps for LB Phone and QS Smartphone. Both apps display the same features — install the one matching your phone system.
LB Phone App | QS Smartphone Appqs-hzweather v2.0.0+ targets QS Smartphone V3 (resource name qs-smartphone). For the legacy V2 build (qs-smartphone-pro), keep using qs-hzweather v1.x. See the QS Smartphone V2 (Pro) section below.Features
- Current weather — condition, temperature, wind speed & direction
- Interactive satellite map — zoom/pan with zone markers and live weather overlay
- Hourly forecast — scrollable forecast per zone
- Sun tracker — animated sunrise/sunset arc synced with game time
- Dynamic backgrounds — animated weather-based backgrounds (rain, snow, sun, clouds, thunder)
- Season display — current season with icon
- Wind card — speed, direction, and compass display
- Zone list — all weather zones with current conditions, clickable to view details
- Current zone indicator — shows which zone the player is currently in
- Real-time updates — auto-refreshes every 30s + instant updates on zone/temperature/season changes
Requirements
Both apps require HZ-Weather to be running on your server.
LB Phone App
| Resource | Version | Link |
|---|---|---|
| HZ-Weather | v1.1.0+ | Hz-Scripts shop |
| LB Phone | Latest | LB Scripts |
| ox_lib | v3.0+ | GitHub |
QS Smartphone V3 App
| Resource | Version | Link |
|---|---|---|
| HZ-Weather | v1.1.4+ | Hz-Scripts shop |
| QS Smartphone | V3+ | Quasar Store |
| ox_lib | v3.0+ | GitHub |
qs-hzweather v2.0.0+ required. v1.x targets the legacy QS Smartphone Pro (V2) — see the V2 section.
Installation
LB Phone
- Download
lb-hzweatherfrom your Keymaster - Place it in your server's
resources/folder - Add to your
server.cfg:
ensure ox_lib
ensure HZ-Weather
ensure lb-phone
ensure lb-hzweather
lb-hzweather must start after lb-phone and HZ-Weather.- Restart your server — the app appears automatically in the LB Phone app list (pre-installed by default).
QS Smartphone V3
- Download
qs-hzweatherv2.0.0+ from your Keymaster - Place it in your server's
resources/folder - Disable the native Weather app. QS Smartphone V3 keeps built-in apps (
phoneApplications) and custom apps (customApps) in two separate routing tables — registering a custom app withid = 'weather'does not override the native (the native always wins). Editqs-smartphone/config/main.lua(around line 1578) and comment out the nativeweatherentry:
Config.PhoneApplications = {
-- { id = 'weather', label = 'Weather', icon = 'weather.webp', category = 'Information & Reading' }, -- disabled: replaced by qs-hzweather
{ id = 'calendar', label = 'Calendar', icon = 'calendar.webp', category = 'Productivity & Finance' },
-- ...
}
Leave firstPageItems = { 'weather', 'calendar' } untouched — our custom app registers under id = 'weather' so the home-screen slot is filled by our iframe.
- Add to your
server.cfg:
ensure ox_lib
ensure HZ-Weather
ensure qs-smartphone
ensure qs-hzweather
qs-hzweather must start after qs-smartphone and HZ-Weather.- Restart your server. Open the phone → the Weather icon now opens our iframe.
qs-hzweather registers a custom app via exports['qs-smartphone']:addCustomApp({ id = 'weather', appStoreOnly = false, iframe = { url = ... }, custom = { enabled = true, bridge = {...} } }). With the native entry disabled, our app is the only one bound to id = 'weather', so the home-screen layout (firstPageItems) lights up our iframe directly. To revert, simply uncomment the native line.qs-hzweather v1.x with qs-smartphone-pro, you need to:
- Stop and remove
qs-smartphone-pro(the V2 resource). - Install QS Smartphone V3 (
qs-smartphone) from Quasar Store. - Update to
qs-hzweatherv2.0.0+ from your Keymaster. - Apply the config edit (step 3 above).
- Reset phone data if needed — V3 uses a different schema than V2:
TRUNCATE TABLE phone_metadata;
TRUNCATE TABLE phone_app_store;
This is only needed once when migrating from V2 to V3.
QS Smartphone V2 (Pro) — legacy
For servers still running QS Smartphone Pro (V2, resource name qs-smartphone-pro), use qs-hzweather v1.x:
- Download
qs-hzweatherv1.x from your Keymaster (older releases tab) - Place it in your server's
resources/folder - Add to your
server.cfg:
ensure ox_lib
ensure HZ-Weather
ensure qs-smartphone-pro
ensure qs-hzweather
- Restart your server — no config edit needed. V2 supports same-id override natively, so the app replaces the native Weather automatically.
Configuration
LB Phone
Edit config.lua in the lb-hzweather resource:
Config.Identifier = "hz-weather" -- Unique app ID (do not change if already deployed)
Config.DefaultApp = true -- true = pre-installed, false = downloadable from app store
Config.Name = "Weather" -- App name shown in phone
Config.Description = "Real-time weather forecast powered by HZ-Weather"
Config.Developer = "HZ Development" -- Developer name in app store
| Parameter | Type | Default | Description |
|---|---|---|---|
Identifier | string | "hz-weather" | Unique app ID — do not change after deployment |
DefaultApp | boolean | true | true = pre-installed, false = app store |
Name | string | "Weather" | Display name in phone |
Description | string | "Real-time..." | App description in app store |
Developer | string | "HZ Development" | Developer name in app store |
QS Smartphone V3
No configuration file in qs-hzweather itself — registration is hardcoded for the weather id. The only edit required is the one-line comment-out in qs-smartphone/config/main.lua documented in step 3 of the install section.
How It Works
Both apps use the same data flow:
Phone UI (React) → NUI Callback → lib.callback → HZ-Weather Server → Response
The app calls lib.callback('hz-weather:getMapData') to fetch all weather data (current weather, zones, forecast, temperatures, wind, season, game time, sunrise/sunset). No server-side Lua file is needed in the app resource — lib.callback handles the client-server round-trip via ox_lib.
Real-time updates are received via client events:
hz_weather:zoneChanged— player changed zonehz_weather:syncTemperatures— temperature updatehz_weather:syncSeason— season change
QS Smartphone V3 — Technical Details
The QS V3 app is registered as a custom app (iframe-based) that visually replaces the native Weather:
- App identifier:
id = 'weather'— registered viaaddCustomApp({ id = 'weather', ... appStoreOnly = false ... }). V3 keepsphoneApplications(native) andcustomApps(third-party) in two separate tables; the native always wins routing, which is why disabling the native config entry is mandatory. - Icon: Served from our resource —
ui/build/icon.svg. The nativeweather.webpis no longer used since the native entry is disabled. - Iframe URL:
https://cfx-nui-qs-hzweather/ui/build/index.html— loaded by QS V3's custom-app iframe component. The iframe doesn't get a sandbox attribute, allows clipboard/camera/microphone. - NUI rendering: The app runs inside V3's iframe slot.
fetchNui()POSTs tohttps://qs-hzweather/...(same-origin to the iframe), hitting ourRegisterNUICallbackhandlers. Thebody { visibility: hidden; display: none }CSS guard is undone explicitly inuseEffect(V2 relied onqs-smartphone-prosending anapp-openedpostMessage to flip it — V3 doesn't). - Bridge SDK (optional): V3 exposes
QSPhoneBridgeathttps://cfx-nui-qs-smartphone/web/build/bridge/qs-phone-bridge.jsfor theme detection, toast notifications, and event communication.qs-hzweathercurrently doesn't use it (30 s polling is enough); future versions may integrate it for instant push. - Widget: The home-screen weather widget is built into QS Smartphone V3 and reads its data from GTA natives independently of HZ-Weather —
qs-hzweatherdoes not control it.
Development
LB Phone App
cd lb-hzweather/ui/
npm install
npm run dev # Hot reload on localhost:3000
Switch to dev mode in fxmanifest.lua:
ui_page "http://localhost:3000/"
-- ui_page "ui/dist/index.html"
Build for production:
npm run build
QS Smartphone V3 App
cd qs-hzweather/ui/
npm install
npm run dev # Hot reload on localhost:5173
Build for production:
npm run build
ui/build/icon.svg still exists. The Vite build process copies files from ui/public/ to ui/build/ — the icon is in public/ and should be preserved automatically.After rebuilding, restart qs-hzweather on the server so QS V3's iframe reloads the new bundle.
Troubleshooting
LB Phone
| Problem | Solution |
|---|---|
| App doesn't appear | Make sure lb-hzweather starts after lb-phone in server.cfg |
| "HZ-Weather is not running" | Ensure HZ-Weather is started before lb-hzweather |
| No weather data | Check that HZ-Weather is properly configured and working |
| Zones not showing on map/list | Update to v1.1.4+ — fixed isActive nil handling |
QS Smartphone V3
| Problem | Solution |
|---|---|
| Tapping Weather opens the native QS screen, not HZ | You skipped step 3 of the install — comment out the native weather entry in qs-smartphone/config/main.lua and restart both qs-smartphone and qs-hzweather. V3 does not auto-override built-in apps by id. |
| Iframe loads but shows a blank white screen | qs-hzweather v1.x bundle running on V3. The V2 build relies on qs-smartphone-pro flipping body { visibility: hidden; display: none } via postMessage — V3 doesn't send that signal. Update to qs-hzweather v2.0.0+ which sets the body visible unconditionally in useEffect. |
| Two Weather apps on the home screen | The native entry is still in Config.PhoneApplications AND our custom app is also registered. Disable the native entry as per install step 3. |
| Weather icon disappears from the home screen | The home layout cached an older state. Open the App Drawer (swipe up), drag Weather back to the home page, or reset the per-player phone layout via the in-game settings. |
[qs-hzweather] addCustomApp failed (…) and updateCustomApp failed (…) in server console | The phone resource refused our registration payload. Check the parenthesized error code — common values are INVALID_PAYLOAD (icon URL or iframe URL malformed) and BRIDGE_DISABLED (custom bridge feature turned off in QS config). Verify ui/build/icon.svg and ui/build/index.html both exist. |
| "Connection error" in the app | Ensure HZ-Weather is started before qs-hzweather. |
| Map tiles not loading | Tiles are served from HZ-Weather — make sure it's running and that the player has network access to cfx-nui-HZ-Weather/web/dist/tiles/. |
Console error about lib.callback | Make sure ox_lib is installed and started before qs-hzweather. |
QS Smartphone V2 (Pro) — legacy
| Problem | Solution |
|---|---|
| "This app was not found" | Reset phone data (see migration note above), then restart server |
| App opens fullscreen instead of in phone | Update to qs-hzweather v1.1.4+ — fixed CSS visibility and 100vh issues |
| 0 locations on map / empty zone list | Update to v1.1.4+ — fixed isActive nil handling |
| "Connection error" in the app | Ensure HZ-Weather is started before qs-hzweather |
| Two Weather apps on home screen | Update to v1.1.4+ — app overrides native Weather app on V2 |
| App doesn't appear at all | Check that qs-smartphone-pro is running and qs-hzweather v1.x starts after it |
| Map tiles not loading | Tiles are served from HZ-Weather — make sure it's running |
| Sunrise/sunset stuck at 6:00/8:00PM | Update to v1.1.4+ — now reads from Config.NightTime |
