From f06ba08b162590f8c1bf89410723f8523f9b0484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Bosi?= <71827178+bosiraphael@users.noreply.github.com> Date: Thu, 9 Jul 2026 16:08:09 +0200 Subject: [PATCH] Fix onboarding locale reverting to English after signup (#22675) During onboarding the UI reverted to English after email verification. The chosen locale was never stored on the user, so the workspace member seeded from it inherited `en`, and after workspace activation `loadCurrentUser` reactivated `en` and flipped the whole UI to English regardless of the browser language. Two changes: **Backend (the actual fix):** the `signUp` resolver received `signUpInput.locale` but only used it for the verification email, creating the user without it (so it defaulted to `en`). It now passes the locale into `signUpWithoutWorkspace`, and the SSO create-a-workspace path forwards `locale` as well. The user, and the workspace member created from it at activation, now keep the chosen locale, so the post-activation reactivation no longer forces English. **Frontend:** carry the active locale across the workspace subdomain redirect (in `useBuildSearchParamsFromUrlSyncedStates`) so the freshly loaded subdomain renders `/verify` in the right language before the current user loads, instead of briefly falling back to the browser default. Minor, only affects the case where the chosen locale differs from the browser language. --- .../hooks/useBuildSearchParamsFromUrlSyncedStates.ts | 2 ++ .../twenty-server/src/engine/core-modules/auth/auth.resolver.ts | 1 + .../src/engine/core-modules/auth/services/auth.service.ts | 1 + 3 files changed, 4 insertions(+) diff --git a/packages/twenty-front/src/modules/domain-manager/hooks/useBuildSearchParamsFromUrlSyncedStates.ts b/packages/twenty-front/src/modules/domain-manager/hooks/useBuildSearchParamsFromUrlSyncedStates.ts index 44a83f4da6..e5b92c2907 100644 --- a/packages/twenty-front/src/modules/domain-manager/hooks/useBuildSearchParamsFromUrlSyncedStates.ts +++ b/packages/twenty-front/src/modules/domain-manager/hooks/useBuildSearchParamsFromUrlSyncedStates.ts @@ -3,6 +3,7 @@ import { useCallback } from 'react'; import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState'; import { returnToPathState } from '@/auth/states/returnToPathState'; import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/settings/billing/constants/BillingCheckoutSessionDefaultValue'; +import { i18n } from '@lingui/core'; import { isNonEmptyString } from '@sniptt/guards'; import { useStore } from 'jotai'; @@ -19,6 +20,7 @@ export const useBuildSearchParamsFromUrlSyncedStates = () => { } : {}), ...(isNonEmptyString(returnToPath) ? { returnToPath } : {}), + ...(isNonEmptyString(i18n.locale) ? { locale: i18n.locale } : {}), }; return output; diff --git a/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts index ce3083bcc9..28d0e39519 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts @@ -398,6 +398,7 @@ export class AuthResolver { const user = await this.signInUpService.signUpWithoutWorkspace( { email: signUpInput.email, + locale: signUpInput.locale, }, { provider: AuthProviderEnum.Password, diff --git a/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts b/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts index 3132a73cab..2ce6cff71a 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts @@ -974,6 +974,7 @@ export class AuthService { lastName, email, picture, + locale, isEmailAlreadyVerified: true, }, {