From b37272cdd78fecc066fa4fa695aa454b3f2c3928 Mon Sep 17 00:00:00 2001 From: Danny White <3104761+dnywh@users.noreply.github.com> Date: Fri, 24 Apr 2026 17:41:59 +1000 Subject: [PATCH] chore(studio + docs) improve project integrations (#45200) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What kind of change does this PR introduce? Docs update and UI copy improvement. ## What is the current behavior? The GitHub integration working directory helper uses an inline tooltip for examples. In the form layout, the tooltip alignment and inline code wrapping can make the helper harder to scan. The integration settings pages also mix markdown-rendered copy with JSX copy, duplicate the integration cover image helper, and use slightly different heading, spacing, and button copy patterns across GitHub, Vercel, and AWS PrivateLink. ## What is the new behavior? The GitHub working directory field now keeps the helper copy concise and links to a dedicated docs section with examples for repository root and nested `supabase/` directories. The integration settings sections now use a more consistent JSX structure and copy treatment across GitHub, Vercel, and AWS PrivateLink, including shared cover imagery and matching explanatory section hierarchy. | Before | After | | --- | --- | | CleanShot 2026-04-24 at 14 35
32@2x | CleanShot 2026-04-24 at 14 30
21@2x-64E8726E-0B89-4C5A-8A47-CE1AA24F3D1A | | CleanShot 2026-04-24 at 14 40
19@2x | CleanShot 2026-04-24 at 14 39
02@2x | ## Summary by CodeRabbit * **Documentation** * Clarified GitHub integration setup: provide a Working directory value, how to compute it from the repo root (including "." for root), examples, and updated “initialize” spelling. * **Refactor** * Simplified integration form descriptions (tooltips → inline text + Learn more link). * Reworked GitHub and Vercel integration content to use consistent headings, layout, and shared image handling. * Reorganized integration settings rendering for clearer UI states. * **Style** * Minor copy, casing, and button text/spacing adjustments. --- .../branching/github-integration.mdx | 10 +- .../IntegrationSettings.tsx | 219 ++++++++++-------- .../AWSPrivateLink/AWSPrivateLinkSection.tsx | 51 ++-- .../GitHubIntegrationConnectionForm.tsx | 38 +-- .../GithubIntegration/GithubSection.tsx | 34 ++- .../VercelIntegration/VercelSection.tsx | 191 ++++++++------- 6 files changed, 268 insertions(+), 275 deletions(-) diff --git a/apps/docs/content/guides/deployment/branching/github-integration.mdx b/apps/docs/content/guides/deployment/branching/github-integration.mdx index ab1969960ed..b0b91b2727f 100644 --- a/apps/docs/content/guides/deployment/branching/github-integration.mdx +++ b/apps/docs/content/guides/deployment/branching/github-integration.mdx @@ -13,13 +13,19 @@ In the Supabase Dashboard: 2. Under **GitHub Integration**, click **Authorize GitHub**. 3. You are redirected to a GitHub authorization page. Click **Authorize Supabase**. 4. You are redirected back to the Integrations page. Choose a GitHub repository to connect your project to. -5. Fill in the relative path to the Supabase directory from your repository root. +5. Set the **Working directory** field. 6. Configure the other options as needed to automate your GitHub connection. 7. Click **Enable integration**. +### Set the working directory + +The working directory is the path from your repository root to the directory that contains the `supabase/` folder. Enter `.` when `supabase/` is at the repository root. + +If `supabase/` is nested deeper in your repository, enter its parent directory instead. For example, if your layout is `apps/web/supabase/`, enter `apps/web`. + ## Preparing your Git repository -You will be using the [Supabase CLI](/docs/guides/cli) to initialise your local `./supabase` directory: +You will be using the [Supabase CLI](/docs/guides/cli) to initialize your local `./supabase` directory: diff --git a/apps/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx b/apps/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx index b8b94310f18..4b5cefdeffb 100644 --- a/apps/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx +++ b/apps/studio/components/interfaces/Organization/IntegrationSettings/IntegrationSettings.tsx @@ -7,7 +7,7 @@ import { GenericSkeletonLoader } from 'ui-patterns' import { IntegrationConnectionItem } from '../../Integrations/VercelGithub/IntegrationConnection' import SidePanelVercelProjectLinker from './SidePanelVercelProjectLinker' import { EmptyIntegrationConnection } from '@/components/interfaces/Integrations/VercelGithub/IntegrationPanels' -import { Markdown } from '@/components/interfaces/Markdown' +import { IntegrationImageHandler } from '@/components/interfaces/Settings/Integrations/IntegrationsSettings' import { VercelSection } from '@/components/interfaces/Settings/Integrations/VercelIntegration/VercelSection' import { ScaffoldContainer, @@ -18,31 +18,124 @@ import { ScaffoldSectionDetail, ScaffoldTitle, } from '@/components/layouts/Scaffold' +import { InlineLink } from '@/components/ui/InlineLink' import NoPermission from '@/components/ui/NoPermission' import { useGitHubAuthorizationQuery } from '@/data/integrations/github-authorization-query' import { useGitHubConnectionDeleteMutation } from '@/data/integrations/github-connection-delete-mutation' -import { useGitHubConnectionsQuery } from '@/data/integrations/github-connections-query' +import { + useGitHubConnectionsQuery, + type GitHubConnection, +} from '@/data/integrations/github-connections-query' import type { IntegrationProjectConnection } from '@/data/integrations/integrations.types' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' -import { BASE_PATH } from '@/lib/constants' import { GITHUB_INTEGRATION_INSTALLATION_URL, GITHUB_INTEGRATION_REVOKE_AUTHORIZATION_URL, } from '@/lib/github' -import { useSidePanelsStateSnapshot } from '@/state/side-panels' -const IntegrationImageHandler = ({ title }: { title: 'vercel' | 'github' }) => { - return ( - {`${title} - ) +type GitHubSectionProps = { + canCreateGitHubConnection: boolean + canReadGithubConnection: boolean + canUpdateGitHubConnection: boolean + connections?: GitHubConnection[] + isGitHubAuthorized: boolean + isLoadingPermissions: boolean + onAddGitHubConnection: () => void + onDeleteGitHubConnection: (connection: IntegrationProjectConnection) => void | Promise } +const GitHubSection = ({ + canCreateGitHubConnection, + canReadGithubConnection, + canUpdateGitHubConnection, + connections, + isGitHubAuthorized, + isLoadingPermissions, + onAddGitHubConnection, + onDeleteGitHubConnection, +}: GitHubSectionProps) => ( + + + +

Connect any of your GitHub repositories to a project.

+ +
+ + {isLoadingPermissions ? ( + + ) : !canReadGithubConnection ? ( + + ) : ( +
+
+

+ How do GitHub connections work? +

+

+ Connect a GitHub repository to a Supabase project. The GitHub app watches file, + branch, and pull request activity in your repository. +

+
+ +
+
    + {connections?.map((connection) => ( + + ))} +
+ + + Add new project connection + +
+ + {isGitHubAuthorized && ( +

+ You are authorized with the Supabase GitHub App. You can configure your{' '} + + GitHub App installations and repository access + + , or{' '} + + revoke your authorization + + . +

+ )} +
+ )} +
+
+
+) + export const IntegrationSettings = () => { const router = useRouter() const { data: org } = useSelectedOrganizationQuery() @@ -69,11 +162,9 @@ export const IntegrationSettings = () => { }, }) - const sidePanelsStateSnapshot = useSidePanelsStateSnapshot() - const onAddGitHubConnection = useCallback(() => { router.push('/project/_/settings/integrations') - }, [sidePanelsStateSnapshot]) + }, [router]) const onDeleteGitHubConnection = useCallback( async (connection: IntegrationProjectConnection) => { @@ -90,99 +181,21 @@ export const IntegrationSettings = () => { [deleteGitHubConnection, org?.id] ) - /** - * GitHub markdown content - */ - - const GitHubTitle = `GitHub Connections` - - const GitHubDetailsSection = ` -Connect any of your GitHub repositories to a project. -` - - const GitHubContentSectionTop = ` - -### How will GitHub connections work? - -You will be able to connect a GitHub repository to a Supabase project. -The GitHub app will watch for changes in your repository such as file changes, branch changes as well as pull request activity. -` - - const GitHubContentSectionBottom = gitHubAuthorization - ? `You are authorized with Supabase GitHub App. You can configure your GitHub App installations and repository access [here](${GITHUB_INTEGRATION_INSTALLATION_URL}). You can revoke your authorization [here](${GITHUB_INTEGRATION_REVOKE_AUTHORIZATION_URL}).` - : '' - - const GitHubSection = () => ( - - - - - - - - {isLoadingPermissions ? ( - - ) : !canReadGithubConnection ? ( - - ) : ( - <> - - -
    - {connections?.map((connection) => ( - - ))} -
- - - Add new project connection - - - {GitHubContentSectionBottom && ( - - )} - - )} -
-
-
- ) - return ( <> Integrations - + {showVercelIntegration && ( <> diff --git a/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLinkSection.tsx b/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLinkSection.tsx index b957acfa684..a503bcd1713 100644 --- a/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLinkSection.tsx +++ b/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLinkSection.tsx @@ -15,6 +15,7 @@ import { import { ResourceList } from '@/components/ui/Resource/ResourceList' import { UpgradeToPro } from '@/components/ui/UpgradeToPro' import { useAWSAccountDeleteMutation } from '@/data/aws-accounts/aws-account-delete-mutation' +import type { AWSAccount } from '@/data/aws-accounts/aws-accounts-query' import { useAWSAccountsQuery } from '@/data/aws-accounts/aws-accounts-query' import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' @@ -24,7 +25,7 @@ export const AWSPrivateLinkSection = () => { const { data: project } = useSelectedProjectQuery() const { data: accounts } = useAWSAccountsQuery({ projectRef: project?.ref }) - const [selectedAccount, setSelectedAccount] = useState(null) + const [selectedAccount, setSelectedAccount] = useState() const [showForm, setShowForm] = useState(false) const [showDeleteModal, setShowDeleteModal] = useState(false) @@ -32,7 +33,7 @@ export const AWSPrivateLinkSection = () => { onSuccess: () => { toast.success('Account will be deleted shortly') setShowDeleteModal(false) - setSelectedAccount(null) + setSelectedAccount(undefined) }, }) @@ -40,16 +41,16 @@ export const AWSPrivateLinkSection = () => { const promptPlanUpgrade = IS_PLATFORM && !hasPrivateLinkAccess const onAddAccount = () => { - setSelectedAccount(null) + setSelectedAccount(undefined) setShowForm(true) } - const onEditAccount = (account: any) => { + const onEditAccount = (account: AWSAccount) => { setSelectedAccount(account) setShowForm(true) } - const onDeleteAccount = (account: any) => { + const onDeleteAccount = (account: AWSAccount) => { setSelectedAccount(account) setShowDeleteModal(true) } @@ -70,31 +71,31 @@ export const AWSPrivateLinkSection = () => {
-
-
- How does the AWS PrivateLink integration work? -
-

- Connecting to AWS PrivateLink allows you to create a private connection between - your AWS VPC and your Supabase project. -

+
+
+

+ How does the AWS PrivateLink integration work? +

+

+ Connecting to AWS PrivateLink allows you to create a private connection between + your AWS VPC and your Supabase project. +

+
{promptPlanUpgrade && ( -
- -
+ )}
-

AWS Accounts

-
{(accounts?.length ?? 0) > 0 ? ( diff --git a/apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GitHubIntegrationConnectionForm.tsx b/apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GitHubIntegrationConnectionForm.tsx index 0080a763683..db61f55cd5a 100644 --- a/apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GitHubIntegrationConnectionForm.tsx +++ b/apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GitHubIntegrationConnectionForm.tsx @@ -30,7 +30,6 @@ import { import { Admonition } from 'ui-patterns/admonition' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' -import { InfoTooltip } from 'ui-patterns/info-tooltip' import * as z from 'zod' import { InlineLink } from '@/components/ui/InlineLink' @@ -461,7 +460,7 @@ export const GitHubIntegrationConnectionForm = ({ render={({ field }) => ( {selectedRepository || connection ? selectedRepository?.name || connection?.repository.name - : 'Choose GitHub Repository'} + : 'Choose GitHub repository'} @@ -584,29 +583,16 @@ export const GitHubIntegrationConnectionForm = ({ layout="flex-row-reverse" label="Working directory" description={ - - Relative path to the directory that contains your{' '} - supabase folder{' '} - - -

Examples:

-
    -
  • - . if repository root - contains supabase/ -
  • -
  • - apps/web if{' '} - supabase/ is nested - at{' '} - - apps/web/supabase/ - -
  • -
-
-
-
+ <> + Relative path to the directory containing your{' '} + supabase/{' '} + folder.{' '} + + Learn more + + } > diff --git a/apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GithubSection.tsx b/apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GithubSection.tsx index a3f032197cf..ac13f40393a 100644 --- a/apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GithubSection.tsx +++ b/apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GithubSection.tsx @@ -1,8 +1,9 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' -import { IS_PLATFORM, useParams } from 'common' +import { useParams } from 'common' import { useMemo } from 'react' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' +import { IntegrationImageHandler } from '../IntegrationsSettings' import { GitHubIntegrationConnectionForm } from './GitHubIntegrationConnectionForm' import { ScaffoldContainer, @@ -14,17 +15,6 @@ import NoPermission from '@/components/ui/NoPermission' import { useGitHubConnectionsQuery } from '@/data/integrations/github-connections-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' -import { BASE_PATH } from '@/lib/constants' - -const IntegrationImageHandler = ({ title }: { title: 'vercel' | 'github' }) => { - return ( - {`${title} - ) -} export const GitHubSection = () => { const { ref: projectRef } = useParams() @@ -59,13 +49,19 @@ export const GitHubSection = () => { ) : (
-
How does the GitHub integration work?
-

- Connecting to GitHub allows you to sync preview branches with a chosen GitHub - branch, keep your production branch in sync, and automatically create preview - branches for every pull request. -

- +
+

+ How does the GitHub integration work? +

+

+ Connecting to GitHub allows you to sync preview branches with a chosen GitHub + branch, keep your production branch in sync, and automatically create preview + branches for every pull request. +

+
+
+ +
)} diff --git a/apps/studio/components/interfaces/Settings/Integrations/VercelIntegration/VercelSection.tsx b/apps/studio/components/interfaces/Settings/Integrations/VercelIntegration/VercelSection.tsx index 3bffb8b81f5..d0832cf7708 100644 --- a/apps/studio/components/interfaces/Settings/Integrations/VercelIntegration/VercelSection.tsx +++ b/apps/studio/components/interfaces/Settings/Integrations/VercelIntegration/VercelSection.tsx @@ -14,13 +14,13 @@ import { IntegrationConnectionHeader, IntegrationInstallation, } from '@/components/interfaces/Integrations/VercelGithub/IntegrationPanels' -import { Markdown } from '@/components/interfaces/Markdown' import { ScaffoldContainer, ScaffoldSection, ScaffoldSectionContent, ScaffoldSectionDetail, } from '@/components/layouts/Scaffold' +import { InlineLink } from '@/components/ui/InlineLink' import NoPermission from '@/components/ui/NoPermission' import { useOrgIntegrationsQuery } from '@/data/integrations/integrations-query-org-only' import { useIntegrationsVercelInstalledConnectionDeleteMutation } from '@/data/integrations/integrations-vercel-installed-connection-delete-mutation' @@ -119,31 +119,8 @@ export const VercelSection = ({ isProjectScoped }: { isProjectScoped: boolean }) [deleteVercelConnection, org?.slug] ) - // Markdown Content const VercelTitle = `Vercel Integration` - const VercelDetailsSection = ` - -Connect your Vercel teams to your Supabase organization. -` - - const VercelContentSectionTop = ` - -### How does the Vercel integration work? - -Supabase will keep your environment variables up to date in each of the projects you assign to a Supabase project. -You can also link multiple Vercel Projects to the same Supabase project. -` - - const VercelContentSectionBottom = - vercelProjectCount > 0 && vercelIntegration !== undefined - ? ` -Your Vercel connection has access to ${vercelProjectCount} Vercel Projects. -You can change the scope of the access for Supabase by configuring -[here](${getIntegrationConfigurationUrl(vercelIntegration)}). -` - : '' - const integrationUrl = process.env.NEXT_PUBLIC_ENVIRONMENT === 'prod' ? 'https://vercel.com/integrations/supabase' @@ -167,7 +144,7 @@ You can change the scope of the access for Supabase by configuring - +

Connect your Vercel teams to your Supabase organization.

@@ -176,87 +153,101 @@ You can change the scope of the access for Supabase by configuring ) : !canReadVercelConnection ? ( ) : ( - <> - - {vercelIntegration ? ( -
- - {connections.length > 0 ? ( - <> +
+
+

+ How does the Vercel integration work? +

+

+ Supabase will keep your environment variables up to date in each of the projects + you assign to a Supabase project. You can also link multiple Vercel projects to + the same Supabase project. +

+
+
+ {vercelIntegration ? ( +
+ + {connections.length > 0 ? ( + <> + +
    + {connections.map((connection) => ( +
    li]:pb-0' + )} + > + + {isProjectScoped ? ( +
    +
    + +
    +
    + ) : null} +
    + ))} +
+ + ) : ( -
    - {connections.map((connection) => ( -
    li]:pb-0' - )} - > - - {isProjectScoped ? ( -
    -
    - -
    -
    - ) : null} -
    - ))} -
- - ) : ( - - )} - onAddVercelConnection(vercelIntegration.id)} - > - Add new project connection - -
- ) : ( -
- -
+ onAddVercelConnection(vercelIntegration.id)} + > + Add new project connection + +
+ ) : ( +
+ +
+ )} +
+ {vercelProjectCount > 0 && vercelIntegration !== undefined && ( +

+ Your Vercel connection can access {vercelProjectCount} Vercel projects. To change + which projects Supabase may use, open your organization’s{' '} + + Vercel integration settings + + . +

)} - {VercelContentSectionBottom && ( - - )} - +
)}