From 8cfcb32de1b21bac36afbbea272c3b98b0b8cb80 Mon Sep 17 00:00:00 2001 From: Oskar Otwinowski Date: Wed, 22 Apr 2026 16:30:16 +0200 Subject: [PATCH] fix(vercel): Fix vercel settings page --- ...ettings-fix-and-onboarding-improvements.md | 6 ++++++ .../integrations/VercelBuildSettings.tsx | 7 +++++-- .../integrations/VercelOnboardingModal.tsx | 20 ++++++++++++++++++- ...cts.$projectParam.env.$envParam.github.tsx | 10 ++++++++-- ...cts.$projectParam.env.$envParam.vercel.tsx | 7 +------ 5 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 .server-changes/vercel-settings-fix-and-onboarding-improvements.md diff --git a/.server-changes/vercel-settings-fix-and-onboarding-improvements.md b/.server-changes/vercel-settings-fix-and-onboarding-improvements.md new file mode 100644 index 00000000000..a78a9012432 --- /dev/null +++ b/.server-changes/vercel-settings-fix-and-onboarding-improvements.md @@ -0,0 +1,6 @@ +--- +area: webapp +type: fix +--- + +Fix Vercel integration settings page (remove redundant section toggles) and improve the Vercel onboarding flow so the modal closes after connecting a GitHub repo and the marketplace `next` URL is preserved across the GitHub app install redirect. diff --git a/apps/webapp/app/components/integrations/VercelBuildSettings.tsx b/apps/webapp/app/components/integrations/VercelBuildSettings.tsx index d665a53f1a1..92d0d0a9992 100644 --- a/apps/webapp/app/components/integrations/VercelBuildSettings.tsx +++ b/apps/webapp/app/components/integrations/VercelBuildSettings.tsx @@ -23,6 +23,8 @@ type BuildSettingsFieldsProps = { disabledEnvSlugs?: Partial>; autoPromote?: boolean; onAutoPromoteChange?: (value: boolean) => void; + /** Hide the section-level master toggles for "Pull env vars" and "Discover new env vars". */ + hideSectionToggles?: boolean; }; export function BuildSettingsFields({ @@ -37,6 +39,7 @@ export function BuildSettingsFields({ disabledEnvSlugs, autoPromote, onAutoPromoteChange, + hideSectionToggles, }: BuildSettingsFieldsProps) { const isSlugDisabled = (slug: EnvSlug) => !!disabledEnvSlugs?.[slug]; const enabledSlugs = availableEnvSlugs.filter((s) => !isSlugDisabled(s)); @@ -48,7 +51,7 @@ export function BuildSettingsFields({
- {availableEnvSlugs.length > 1 && ( + {!hideSectionToggles && availableEnvSlugs.length > 1 && (
- {availableEnvSlugs.length > 1 && ( + {!hideSectionToggles && availableEnvSlugs.length > 1 && ( { + if (state === "github-connection" && isGitHubConnectedForOnboarding) { + trackOnboarding("vercel onboarding github completed"); + if (fromMarketplaceContext && nextUrl) { + const validUrl = safeRedirectUrl(nextUrl); + if (validUrl) { + window.location.href = validUrl; + return; + } + } + setState("completed"); + } + }, [state, isGitHubConnectedForOnboarding, fromMarketplaceContext, nextUrl, trackOnboarding]); + useEffect(() => { if (state === "completed" && !hasTrackedCompletionRef.current) { hasTrackedCompletionRef.current = true; @@ -1114,6 +1128,7 @@ export function VercelOnboardingModal({ redirectParams.set("next", nextUrl); } const redirectUrlWithContext = `${baseSettingsPath}?${redirectParams.toString()}`; + const nextDirectRedirect = nextUrl ? safeRedirectUrl(nextUrl) : null; return gitHubAppInstallations.length === 0 ? (
@@ -1137,7 +1152,10 @@ export function VercelOnboardingModal({ organizationSlug={organizationSlug} projectSlug={projectSlug} environmentSlug={environmentSlug} - redirectUrl={redirectUrlWithContext} + redirectUrl={ + nextDirectRedirect ?? + (fromMarketplaceContext ? redirectUrlWithContext : baseSettingsPath) + } preventDismiss={fromMarketplaceContext} /> diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github.tsx index 15062a718bc..fe1b32f8925 100644 --- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github.tsx +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github.tsx @@ -865,8 +865,14 @@ export function GitHubSettingsPanel({ const fetcher = useTypedFetcher(); const location = useLocation(); - // Use provided redirectUrl or fall back to current path (without search params) - const effectiveRedirectUrl = location.pathname; + // Preserve current search params (e.g. origin=marketplace, next=...) but strip + // openGithubRepoModal so the modal doesn't re-open in a loop after the action redirect. + const effectiveRedirectUrl = (() => { + const params = new URLSearchParams(location.search); + params.delete("openGithubRepoModal"); + const search = params.toString(); + return search ? `${location.pathname}?${search}` : location.pathname; + })(); useEffect(() => { fetcher.load(gitHubResourcePath(organizationSlug, projectSlug, environmentSlug)); }, [organizationSlug, projectSlug, environmentSlug]); diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx index d6131083bdf..a37d85b0a56 100644 --- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx @@ -819,6 +819,7 @@ function ConnectedVercelProjectForm({ onAutoPromoteChange={(value) => setConfigValues((prev) => ({ ...prev, autoPromote: value })) } + hideSectionToggles /> {/* Warning: autoAssignCustomDomains must be disabled for atomic deployments */} @@ -904,12 +905,6 @@ function VercelSettingsPanel({ } }, [organizationSlug, projectSlug, environmentSlug, data?.authInvalid, hasError, data, hasFetched]); - useEffect(() => { - if (hasFetched && fetcher.state === "idle" && fetcher.data === undefined && !hasError) { - setHasError(true); - } - }, [fetcher.state, fetcher.data, hasError, hasFetched]); - if (hasError) { return (