From b044408e79cc25299139c68959863e6f06cc1e4d Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Mon, 17 Aug 2026 17:15:53 +0800 Subject: [PATCH] [FE-4185] feat(studio): custom content key for auth page logo link (#49130) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a `dashboard_auth:logo_link_url` custom content key so white-labeled deployments can point the logged-out logo link at their own marketing site instead of the hardcoded `https://supabase.com`. **Added:** - `dashboard_auth:logo_link_url` custom content key (schema, types, default `null`, sample value) **Changed:** - `SignInLayout` and `ForgotPasswordLayout` now resolve the marketing-site logo href from custom content, falling back to `https://supabase.com` — these two shared layouts cover all auth pages (sign-in, sign-in-sso, sign-in-mfa, sign-in-partner, forgot/reset password) in both the Next and TanStack runtimes ## To test - On a normal deployment (key `null`): visit `/sign-in` and `/forgot-password` logged out — the logo should still link to `https://supabase.com` - Set `"dashboard_auth:logo_link_url": "https://example.com"` in `apps/studio/hooks/custom-content/custom-content.json` locally — the logo on those pages should link to `https://example.com` - Signed-in contexts (`logoLinkToMarketingSite` unset) still link to `/organizations` ## Summary by CodeRabbit * **New Features** * Added support for configuring the URL linked from authentication-page logos. * Authentication logos now use the configured destination when available. * Added a default destination to ensure logo links remain functional when no custom URL is set. * **Documentation** * Added sample configuration for the customizable authentication logo link. --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Joshen Lim --- .../components/layouts/SignInLayout/ForgotPasswordLayout.tsx | 5 ++++- apps/studio/components/layouts/SignInLayout/SignInLayout.tsx | 5 ++++- apps/studio/hooks/custom-content/CustomContent.types.ts | 2 ++ apps/studio/hooks/custom-content/custom-content.json | 2 ++ apps/studio/hooks/custom-content/custom-content.sample.json | 2 ++ apps/studio/hooks/custom-content/custom-content.schema.json | 5 +++++ 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/studio/components/layouts/SignInLayout/ForgotPasswordLayout.tsx b/apps/studio/components/layouts/SignInLayout/ForgotPasswordLayout.tsx index c7b24a8d3b2..2b0824e92df 100644 --- a/apps/studio/components/layouts/SignInLayout/ForgotPasswordLayout.tsx +++ b/apps/studio/components/layouts/SignInLayout/ForgotPasswordLayout.tsx @@ -4,6 +4,7 @@ import Link from 'next/link' import { PropsWithChildren, useEffect, useState } from 'react' import { cn } from 'ui' +import { useCustomContent } from '@/hooks/custom-content/useCustomContent' import { BASE_PATH } from '@/lib/constants' type ForgotPasswordLayoutProps = { @@ -23,6 +24,8 @@ export const ForgotPasswordLayout = ({ children, }: PropsWithChildren) => { const { resolvedTheme } = useTheme() + const { dashboardAuthLogoLinkUrl } = useCustomContent(['dashboard_auth:logo_link_url']) + const marketingSiteUrl = dashboardAuthLogoLinkUrl ?? 'https://supabase.com' // Addresses hydration issue with `resolvedTheme` as its undefined during SSR and the first (hydrating) client render const [mounted, setMounted] = useState(false) @@ -39,7 +42,7 @@ export const ForgotPasswordLayout = ({