Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion packages/clerk-js/src/core/resources/SignUp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
generateSignatureWithMetamask,
generateSignatureWithOKXWallet,
getBaseIdentifier,
getBrowserLocale,
getClerkQueryParam,
getCoinbaseWalletIdentifier,
getMetamaskIdentifier,
Expand Down Expand Up @@ -95,6 +96,7 @@ export class SignUp extends BaseResource implements SignUpResource {
createdUserId: string | null = null;
abandonAt: number | null = null;
legalAcceptedAt: number | null = null;
locale: string | null = null;

/**
* The current status of the sign-up process.
Expand Down Expand Up @@ -154,6 +156,11 @@ export class SignUp extends BaseResource implements SignUpResource {

let finalParams = { ...params };

// Inject browser locale if not already provided
if (!finalParams.locale) {
finalParams.locale = getBrowserLocale();
}

if (!__BUILD_DISABLE_RHC__ && !this.clientBypass() && !this.shouldBypassCaptchaForAttempt(params)) {
const captchaChallenge = new CaptchaChallenge(SignUp.clerk);
const captchaParams = await captchaChallenge.managedOrInvisible({ action: 'signup' });
Expand Down Expand Up @@ -677,7 +684,9 @@ class SignUpFuture implements SignUpFutureResource {

async create(params: SignUpFutureCreateParams): Promise<{ error: unknown }> {
return runAsyncResourceTask(this.resource, async () => {
await this._create(params);
// Inject browser locale if not already provided
const locale = params.locale || getBrowserLocale();
await this._create({ ...params, locale });
});
}

Expand Down
41 changes: 41 additions & 0 deletions packages/clerk-js/src/utils/__tests__/locale.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, expect, it } from 'vitest';

import { getBrowserLocale } from '../locale';

describe('getBrowserLocale()', () => {
it('returns the browser locale when available', () => {
Object.defineProperty(window.navigator, 'language', {
value: 'es-ES',
configurable: true,
});

expect(getBrowserLocale()).toBe('es-ES');
});

it('returns en-US as default when navigator.language is not available', () => {
Object.defineProperty(window.navigator, 'language', {
value: undefined,
configurable: true,
});

expect(getBrowserLocale()).toBe('en-US');
});

it('returns en-US when navigator.language is empty string', () => {
Object.defineProperty(window.navigator, 'language', {
value: '',
configurable: true,
});

expect(getBrowserLocale()).toBe('en-US');
});

it('returns en-US when navigator object is not defined', () => {
Object.defineProperty(window, 'navigator', {
value: undefined,
configurable: true,
});

expect(getBrowserLocale()).toBe('en-US');
});
});
1 change: 1 addition & 0 deletions packages/clerk-js/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export * from './props';
export * from './queryStateParams';
export * from './querystring';
export * from './runtime';
export * from './locale';
export * from './url';
export * from './web3';
export * from './windowNavigate';
25 changes: 25 additions & 0 deletions packages/clerk-js/src/utils/locale.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { inBrowser } from '@clerk/shared/browser';

const DEFAULT_LOCALE = 'en-US';

/**
* Detects the user's preferred locale from the browser.
* Falls back to 'en-US' if locale cannot be determined.
*
* @returns The detected locale string in BCP 47 format (e.g., 'en-US', 'es-ES')
*/
export function getBrowserLocale(): string {
if (!inBrowser()) {
return DEFAULT_LOCALE;
}

// Get locale from the browser
const locale = navigator?.language;

// Validate that we got a non-empty string
if (!locale || typeof locale !== 'string' || locale.trim() === '') {
return DEFAULT_LOCALE;
}

return locale;
}
1 change: 1 addition & 0 deletions packages/types/src/signUp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface SignUpResource extends ClerkResource {
createdUserId: string | null;
abandonAt: number | null;
legalAcceptedAt: number | null;
locale: string | null;

create: (params: SignUpCreateParams) => Promise<SignUpResource>;

Expand Down
1 change: 1 addition & 0 deletions packages/types/src/signUpCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export type SignUpCreateParams = Partial<
oidcPrompt: string;
oidcLoginHint: string;
channel: PhoneCodeChannel;
locale?: string;
} & Omit<SnakeToCamel<Record<SignUpAttributeField | SignUpVerifiableField, string>>, 'legalAccepted'>
>;

Expand Down
1 change: 1 addition & 0 deletions packages/types/src/signUpFuture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface SignUpFutureAdditionalParams {
lastName?: string;
unsafeMetadata?: SignUpUnsafeMetadata;
legalAccepted?: boolean;
locale?: string;
}

export interface SignUpFutureCreateParams extends SignUpFutureAdditionalParams {
Expand Down
5 changes: 4 additions & 1 deletion playground/app-router/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ yarn-debug.log*
yarn-error.log*

# local env files
.env*.local
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# clerk configuration (can include secrets)
/.clerk/
4 changes: 2 additions & 2 deletions playground/app-router/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ yarn dev
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
Open [http://localhost:4011](http://localhost:4011) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

[http://localhost:3000/api/hello](http://localhost:3000/api/hello) is an endpoint that uses [Route Handlers](https://nextjs.org/docs/routing/route-handlers). This endpoint can be edited in `app/api/hello/route.ts`.
[http://localhost:4011/api/hello](http://localhost:4011/api/hello) is an endpoint that uses [Route Handlers](https://nextjs.org/docs/routing/route-handlers). This endpoint can be edited in `app/api/hello/route.ts`.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

Expand Down
Loading