diff --git a/.pr/cloud-settings-button-closeup.png b/.pr/cloud-settings-button-closeup.png
new file mode 100644
index 0000000000..716cbc9943
Binary files /dev/null and b/.pr/cloud-settings-button-closeup.png differ
diff --git a/.pr/cloud-settings-button-hidden-local-backend.png b/.pr/cloud-settings-button-hidden-local-backend.png
new file mode 100644
index 0000000000..d6d1bff7fe
Binary files /dev/null and b/.pr/cloud-settings-button-hidden-local-backend.png differ
diff --git a/.pr/cloud-settings-button-visible.png b/.pr/cloud-settings-button-visible.png
new file mode 100644
index 0000000000..15a21c9e25
Binary files /dev/null and b/.pr/cloud-settings-button-visible.png differ
diff --git a/__tests__/components/features/settings/cloud-settings-link.test.tsx b/__tests__/components/features/settings/cloud-settings-link.test.tsx
new file mode 100644
index 0000000000..d6bc200577
--- /dev/null
+++ b/__tests__/components/features/settings/cloud-settings-link.test.tsx
@@ -0,0 +1,96 @@
+import { describe, it, expect, beforeEach, afterEach } from "vitest";
+import { render, screen } from "@testing-library/react";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import {
+ __resetActiveStoreForTests,
+ setActiveSelection,
+ setRegisteredBackends,
+} from "#/api/backend-registry/active-store";
+import type { Backend } from "#/api/backend-registry/types";
+import { ActiveBackendProvider } from "#/contexts/active-backend-context";
+import { CloudSettingsLink } from "#/components/features/settings/cloud-settings-link";
+
+const cloudBackend: Backend = {
+ id: "cloud-1",
+ name: "OpenHands Cloud",
+ host: "https://app.all-hands.dev",
+ apiKey: "token",
+ kind: "cloud",
+};
+
+const localBackend: Backend = {
+ id: "local-1",
+ name: "Local",
+ host: "http://localhost:3001",
+ apiKey: "local-key",
+ kind: "local",
+};
+
+function renderWithProviders() {
+ const queryClient = new QueryClient({
+ defaultOptions: { queries: { retry: false } },
+ });
+ return render(
+
+
+
+
+ ,
+ );
+}
+
+beforeEach(() => {
+ window.localStorage.clear();
+ __resetActiveStoreForTests();
+});
+
+afterEach(() => {
+ window.localStorage.clear();
+ __resetActiveStoreForTests();
+});
+
+describe("CloudSettingsLink", () => {
+ it("renders a link to {cloudHost}/settings when a cloud backend is active", () => {
+ setRegisteredBackends([cloudBackend]);
+ setActiveSelection({ backendId: cloudBackend.id });
+
+ renderWithProviders();
+
+ const link = screen.getByTestId("settings-cloud-link");
+ expect(link).toHaveAttribute("href", "https://app.all-hands.dev/settings");
+ expect(link).toHaveAttribute("target", "_blank");
+ expect(link).toHaveAttribute("rel", "noopener noreferrer");
+ // The test i18n mock returns the key verbatim; the human label
+ // ("Cloud") is exercised via the translation.json entry instead.
+ expect(link).toHaveTextContent("SETTINGS$CLOUD_SETTINGS_LINK");
+ });
+
+ it("strips a trailing slash when building the cloud settings URL", () => {
+ setRegisteredBackends([
+ { ...cloudBackend, host: "https://app.all-hands.dev/" },
+ ]);
+ setActiveSelection({ backendId: cloudBackend.id });
+
+ renderWithProviders();
+
+ expect(screen.getByTestId("settings-cloud-link")).toHaveAttribute(
+ "href",
+ "https://app.all-hands.dev/settings",
+ );
+ });
+
+ it("renders nothing when a local backend is active", () => {
+ setRegisteredBackends([localBackend]);
+ setActiveSelection({ backendId: localBackend.id });
+
+ renderWithProviders();
+
+ expect(screen.queryByTestId("settings-cloud-link")).toBeNull();
+ });
+
+ it("renders nothing when no backend is configured", () => {
+ renderWithProviders();
+
+ expect(screen.queryByTestId("settings-cloud-link")).toBeNull();
+ });
+});
diff --git a/scripts/check-translation-completeness.cjs b/scripts/check-translation-completeness.cjs
index 63f39b4c03..f6a2e17999 100755
--- a/scripts/check-translation-completeness.cjs
+++ b/scripts/check-translation-completeness.cjs
@@ -34,6 +34,7 @@ const IDENTICAL_VALUE_ALLOWLIST = new Set([
'SETTINGS$AGENT_SERVER_URL_PLACEHOLDER',
'SETTINGS$AGENT_TYPE_OPENHANDS',
'SETTINGS$AZURE_DEVOPS',
+ 'SETTINGS$CLOUD_SETTINGS_LINK',
'SETTINGS$GITHUB',
'SETTINGS$GITLAB',
'SETTINGS$MCP_DEFAULT_CONFIG',
diff --git a/src/components/features/settings/cloud-settings-link.tsx b/src/components/features/settings/cloud-settings-link.tsx
new file mode 100644
index 0000000000..445b44dd2c
--- /dev/null
+++ b/src/components/features/settings/cloud-settings-link.tsx
@@ -0,0 +1,50 @@
+import { useTranslation } from "react-i18next";
+import { Cloud, ExternalLink } from "lucide-react";
+import { I18nKey } from "#/i18n/declaration";
+import { useActiveBackendContext } from "#/contexts/active-backend-context";
+import { isNoBackend } from "#/api/backend-registry/active-store";
+import { cn } from "#/utils/utils";
+import {
+ SIDEBAR_ICON_SLOT_CLASS,
+ SIDEBAR_ROW_INTERACTIVE_CLASS,
+ sidebarNavLabelClassName,
+ sidebarNavRowClassName,
+} from "#/components/features/sidebar/sidebar-layout";
+
+/**
+ * Renders only for cloud backends — local backends have no equivalent
+ * hosted settings page.
+ */
+export function CloudSettingsLink() {
+ const { t } = useTranslation("openhands");
+ const { active } = useActiveBackendContext();
+ const { backend } = active;
+
+ if (isNoBackend(backend) || backend.kind !== "cloud") return null;
+
+ const cloudSettingsUrl = `${backend.host.replace(/\/+$/, "")}/settings`;
+
+ return (
+
+
+
+
+
+ {t(I18nKey.SETTINGS$CLOUD_SETTINGS_LINK)}
+
+
+
+ );
+}
diff --git a/src/components/features/settings/settings-desktop-sidebar.tsx b/src/components/features/settings/settings-desktop-sidebar.tsx
index 39fc47c82d..6464481d37 100644
--- a/src/components/features/settings/settings-desktop-sidebar.tsx
+++ b/src/components/features/settings/settings-desktop-sidebar.tsx
@@ -5,6 +5,7 @@ import { I18nKey } from "#/i18n/declaration";
import { SettingsNavRenderedItem } from "#/hooks/use-settings-nav-items";
import { SidebarNavLink } from "#/components/features/sidebar/sidebar-nav-link";
import { BackendSyncedSettingsBadge } from "#/components/features/settings/backend-synced-settings-badge";
+import { CloudSettingsLink } from "#/components/features/settings/cloud-settings-link";
interface SettingsDesktopSidebarProps {
navigationItems: SettingsNavRenderedItem[];
@@ -61,6 +62,7 @@ export function SettingsDesktopSidebar({
}
/>
))}
+
diff --git a/src/components/features/settings/settings-mobile-drawer.tsx b/src/components/features/settings/settings-mobile-drawer.tsx
index 13d323e65f..8c1e941ad4 100644
--- a/src/components/features/settings/settings-mobile-drawer.tsx
+++ b/src/components/features/settings/settings-mobile-drawer.tsx
@@ -10,6 +10,7 @@ import { SettingsNavDivider } from "./settings-nav-divider";
import { SettingsNavLink } from "./settings-nav-link";
import { navInteractiveTransitionClassName } from "#/components/features/sidebar/sidebar-layout";
import { BackendSyncedSettingsBadge } from "#/components/features/settings/backend-synced-settings-badge";
+import { CloudSettingsLink } from "#/components/features/settings/cloud-settings-link";
interface SettingsMobileDrawerProps {
isMobileMenuOpen: boolean;
@@ -87,6 +88,7 @@ export function SettingsMobileDrawer({
/>
);
})}
+
diff --git a/src/components/features/settings/settings-mobile-hub.tsx b/src/components/features/settings/settings-mobile-hub.tsx
index 9aca31b9f4..3ccd8ff19b 100644
--- a/src/components/features/settings/settings-mobile-hub.tsx
+++ b/src/components/features/settings/settings-mobile-hub.tsx
@@ -4,6 +4,7 @@ import { I18nKey } from "#/i18n/declaration";
import { SettingsNavRenderedItem } from "#/hooks/use-settings-nav-items";
import { SidebarNavLink } from "#/components/features/sidebar/sidebar-nav-link";
import { BackendSyncedSettingsBadge } from "#/components/features/settings/backend-synced-settings-badge";
+import { CloudSettingsLink } from "#/components/features/settings/cloud-settings-link";
interface SettingsMobileHubProps {
navigationItems: SettingsNavRenderedItem[];
@@ -34,6 +35,7 @@ export function SettingsMobileHub({ navigationItems }: SettingsMobileHubProps) {
icon={renderedItem.item.icon}
/>
))}
+
diff --git a/src/i18n/translation.json b/src/i18n/translation.json
index 57712d72cb..9488656888 100644
--- a/src/i18n/translation.json
+++ b/src/i18n/translation.json
@@ -27539,6 +27539,23 @@
"uk": "Ці налаштування синхронізовано з бекендом {{name}} ({{host}})",
"ca": "Aquesta configuració està sincronitzada amb el backend {{name}} ({{host}})"
},
+ "SETTINGS$CLOUD_SETTINGS_LINK": {
+ "en": "Cloud",
+ "ja": "Cloud",
+ "zh-CN": "Cloud",
+ "zh-TW": "Cloud",
+ "ko-KR": "Cloud",
+ "no": "Cloud",
+ "it": "Cloud",
+ "pt": "Cloud",
+ "es": "Cloud",
+ "ar": "Cloud",
+ "fr": "Cloud",
+ "tr": "Cloud",
+ "de": "Cloud",
+ "uk": "Cloud",
+ "ca": "Cloud"
+ },
"BACKEND$REMOVE": {
"en": "Remove",
"ja": "削除",