fix(weather): handle disabled external connections (#6780)

This commit is contained in:
Thomas authored and GitHub committed 2026-09-06 15:35:06 +02:00
1 parent 50a3bcce69
commit 724dee55c5
5 files changed
+20 -6

No files matched your search

@@ -31,7 +31,7 @@ Using the `PUID` and `PGID` will require you to set the correct permissions on t
| `PGID` | Group ID to run the container as | Any valid group ID | `0` |
| `LOG_LEVEL` | Log level to use | `debug` / `info` / `warn` / `error` | `info` |
| `BASE_URL` | Public Homarr origin used by MCP OAuth metadata and redirects. Set this when a reverse proxy does not preserve the public host and protocol. | HTTP(S) origin without a path | - |
| `NO_EXTERNAL_CONNECTION` | Disables Homarr's internet-backed requests, including update checks, weather, and RSS feeds | `true` or `false` | `false` |
| `NO_EXTERNAL_CONNECTION` | Disables Homarr's internet-backed requests, including update checks, weather, location search, and RSS feeds | `true` or `false` | `false` |
| `ENABLE_DNS_CACHING` | Enables dns caching. Enabled by default, but if you experience issues with IPv6 or static IPs, see [#4006](https://github.com/homarr-labs/homarr/issues/4006) or disable this flag | `true` or `false` | `true` |
| `HOMARR_DISABLE_IPV6` | Disables the IPv6 listener of the internal nginx proxy, even when the host supports IPv6. IPv6 is normally disabled automatically when the host has no IPv6 configured. See [#4596](https://github.com/homarr-labs/homarr/issues/4596) | `true` or `false` | `false` |
| `HOMARR_WEBSITE_URL` | Main Homarr documentation/site base used by runtime links. Must be an absolute HTTP(S) URL. | HTTP(S) URL | `https://homarr.dev` |
+3 -2
View File
@@ -31,5 +31,6 @@ adds hourly temperature and precipitation charts and the complete seven-day fore
Weather and location data come from Open-Meteo. Active weather refreshes every ten minutes; identical location requests
can reuse a server response for five minutes. Failed refreshes keep the last successful data with an error indicator.
Set `NO_EXTERNAL_CONNECTION=true` to disable this and other internet-backed requests. Allowlist
`https://open-meteo.com` when outbound access is restricted.
Set `NO_EXTERNAL_CONNECTION=true` to disable this and other internet-backed requests. Weather data and the city search
inside the widget configuration are unavailable while it is enabled. Allowlist `https://open-meteo.com` when outbound
access is restricted.
+3
View File
@@ -1,5 +1,6 @@
import { z } from "zod/v4";
import { env } from "@homarr/common/env";
import { fetchWithTrustedCertificatesAsync } from "@homarr/core/infrastructure/http";
import { withTimeoutAsync } from "@homarr/core/infrastructure/http/timeout";
@@ -37,6 +38,8 @@ export const locationRouter = createTRPCRouter({
.input(locationSearchCityInput)
.output(locationSearchCityOutput)
.query(async ({ input }) => {
if (env.NO_EXTERNAL_CONNECTION) return { results: [] };
const url = new URL("https://geocoding-api.open-meteo.com/v1/search");
url.searchParams.set("name", input.query);
const res = await withTimeoutAsync(async (signal) => {
+1
View File
@@ -3125,6 +3125,7 @@
}
},
"currentWindSpeed": "{currentWindSpeed} {unit}",
"disabled": "Weather data is unavailable because outbound connections are disabled",
"dailyForecast": {
"sunrise": "Sunrise",
"sunset": "Sunset",
+12 -3
View File
@@ -1,10 +1,10 @@
"use client";
import { Box } from "@mantine/core";
import { Box, Center, Text } from "@mantine/core";
import { clientApi } from "@homarr/api/client";
import { useI18n } from "@homarr/translation/client";
import { WidgetEmptyState } from "../common/empty-state";
import { getUsableWidgetQueryData, isInitialWidgetQueryPending } from "../common/query-state";
import { WidgetQueryLoadingState } from "../common/query-state-indicator";
import type { WidgetComponentProps } from "../definition";
@@ -19,6 +19,7 @@ export default function WeatherWidget({
height,
displayMode,
}: WidgetComponentProps<"weather">) {
const t = useI18n("widget.weather");
const input = {
latitude: options.location.latitude,
longitude: options.location.longitude,
@@ -27,7 +28,15 @@ export default function WeatherWidget({
const weather = getUsableWidgetQueryData(weatherQuery);
if (isInitialWidgetQueryPending(weatherQuery)) return <WidgetQueryLoadingState />;
if (!weather) return <WidgetEmptyState />;
if (!weather) {
return (
<Center h="100%" w="100%" p="sm">
<Text c="dimmed" size="sm" ta="center">
{t("disabled")}
</Text>
</Center>
);
}
return (
<Box className={classes.weatherSurface} h="100%" w="100%" pos="relative">