Localization prop (experimental)
Clerk offers the ability to override the strings for all of the elements in each of the Clerk components. This allows you to provide localization for your users or change the wording to suit your brand.
@clerk/localizations
The @clerk/localizations
package contains predefined localizations for the Clerk components.
Languages
Clerk currently supports the following languages with English as the default:
English name | Language tag (BCP 47) | Key |
---|---|---|
Arabic (Saudi) | ar-SA | arSA |
Belarus | be-BY | beBY |
Bulgarian | bg-BG | bgBG |
Catalan | ca-ES | caES |
Czech | cs-CZ | csCZ |
Danish | da-DK | daDK |
German | de-DE | deDE |
Greek | el-GR | elGR |
English (US) | en-US | enUS |
Spanish | es-ES | esES |
Spanish (Mexico) | es-MX | esMX |
Finnish | fi-FI | fiFI |
French | fr-FR | frFR |
Hebrew | he-IL | heIL |
Croatian | hr-HR | hrHR |
Hungarian | hu-HU | huHU |
Icelandic | is-IS | isIS |
Italian | it-IT | itIT |
Japanese | ja-JP | jaJP |
Korean | ko-KR | koKR |
Mongolian | mn-MN | mnMN |
Norwegian | nb-NO | nbNO |
Dutch | nl-BE | nlBE |
Dutch | nl-NL | nlNL |
Polish | pl-PL | plPL |
Portuguese (BR) | pt-BR | ptBR |
Portuguese (PT) | pt-PT | ptPT |
Romanian | ro-RO | roRO |
Russian | ru-RU | ruRU |
Slovak | sk-SK | skSK |
Swedish | sv-SE | svSE |
Thai | th-TH | thTH |
Turkish | tr-TR | trTR |
Ukrainian | uk-UA | ukUA |
Vietnamese | vi-VN | viVN |
Chinese (Simplified) | zh-CN | zhCN |
Chinese (Traditional) | zh-TW | zhTW |
Usage
To get started, install the @clerk/localizations
package.
npm install @clerk/localizations
yarn add @clerk/localizations
pnpm add @clerk/localizations
Once the @clerk/localizations
package is installed, you can import the localizations you need by removing the "-" from the locale.
In the following example, the fr-FR locale is imported as frFR
. The imported localization is then passed to the localization
prop on the <ClerkProvider>
.
import { ClerkProvider } from '@clerk/nextjs'
import './globals.css'
// fr-FR locale is imported as frFR
import { frFR } from '@clerk/localizations'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider localization={frFR}>
<html lang="en">
<body>{children}</body>
</html>
</ClerkProvider>
)
}
import { ClerkProvider } from '@clerk/nextjs'
// fr-FR locale is imported as frFR
import { frFR } from '@clerk/localizations'
import type { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return (
// Add the localization prop to the ClerkProvider
<ClerkProvider localization={frFR} {...pageProps}>
<Component {...pageProps} />
</ClerkProvider>
)
}
export default MyApp
In the following example, the fr-FR locale is imported as frFR
. The imported localization is then passed to the localization
prop in the ClerkApp
options.
import type { MetaFunction, LoaderFunction } from '@remix-run/node'
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react'
import { rootAuthLoader } from '@clerk/remix/ssr.server'
// Import ClerkApp
import { ClerkApp } from '@clerk/remix'
// fr-FR locale is imported as frFR
import { frFR } from '@clerk/localizations'
export const meta: MetaFunction = () => [
{
charset: 'utf-8',
title: 'New Remix App',
viewport: 'width=device-width,initial-scale=1',
},
]
export const loader: LoaderFunction = (args) => rootAuthLoader(args)
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
)
}
function App() {
return <Outlet />
}
export default ClerkApp(App, {
localization: frFR,
})
import clerk from '@clerk/astro'
// fr-FR locale is imported as frFR
import { frFR } from '@clerk/localizations'
export default defineConfig({
integrations: [
clerk({
localization: frFR,
}),
],
})
In the following example, the fr-FR locale is imported as frFR
. The imported localization is then passed to the localization
prop on the clerk.load()
method.
Use the following tabs to view the code necessary for each file.
import { Clerk } from '@clerk/clerk-js'
// fr-FR locale is imported as frFR
import { frFR } from '@clerk/localizations'
const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY
const clerk = new Clerk(clerkPubKey)
await clerk.load({
localization: frFR,
})
if (clerk.user) {
document.getElementById('app').innerHTML = `
<div id="user-button"></div>
`
const userButtonDiv = document.getElementById('user-button')
clerk.mountUserButton(userButtonDiv)
} else {
document.getElementById('app').innerHTML = `
<div id="sign-in"></div>
`
const signInDiv = document.getElementById('sign-in')
clerk.mountSignIn(signInDiv)
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Clerk + JavaScript App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="main.js" async crossorigin="anonymous"></script>
</body>
</html>
import { createApp } from 'vue'
import App from './App.vue'
import { clerkPlugin } from '@clerk/vue'
// fr-FR locale is imported as frFR
import { frFR } from '@clerk/localizations'
const app = createApp(App)
app.use(clerkPlugin, {
localization: frFR,
})
app.mount('#app')
// fr-FR locale is imported as frFR
import { frFR } from '@clerk/localizations'
export default defineNuxtConfig({
modules: ['@clerk/nuxt'],
clerk: {
localization: frFR,
},
})
Adding or updating a localization
Our localizations are customer-sourced and we encourage customers to add or update localizations. To do so, follow these steps:
- Fork the https://github.com/clerk/javascript/ repo.
- Clone it locally to edit it.
- Review our Contributing guide.
- If you are updating an existing localization locate the file in
packages/localizations/src
- If you are adding a new language, copy the
en-US.ts
file and name it according to your language. The naming is the abbreviated language-region. For example, for French in Canada, it would befr-CA.ts.
- Go through the file and edit the entries.
- If you are adding a new localization, add the language to the
packages/localizations/src/index.ts
file. - Commit your changes to git and push them to your fork. Create a Pull Request from your fork to Clerk's repo against the
main
branch. We will review and either approve or ask for updates.
Custom localizations
You can also provide your own localizations for the Clerk components. This is useful if you want to provide limited or quick localization for a language that Clerk doesn't currently support or if you want to change the wording to suit your brand.
Usage
import { ClerkProvider } from '@clerk/nextjs'
import './globals.css'
// fr-FR locale is imported as frFR
import { frFR } from '@clerk/localizations'
const localization = {
socialButtonsBlockButton: 'Sign In with {{provider|titleize}}',
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider localization={localization}>
<html lang="en">
<body>{children}</body>
</html>
</ClerkProvider>
)
}
To find the key for your translation (like the socialButtonsBlockButton
from the code example below), open up our English localization file. Search the file for the term that you want to customize.
For example, if you want to change the 'to continue to' string from the <SignIn />
and <SignUp />
components, you would search for 'to continue to'. You will find several instances of this. Some of those are in the the following signUp
object:
signUp: {
start: {
title: 'Create your account',
subtitle: 'to continue to {{applicationName}}',
actionText: 'Have an account?',
actionLink: 'Sign in',
},
emailLink: {
title: 'Verify your email',
subtitle: 'to continue to {{applicationName}}',
formTitle: 'Verification link',
formSubtitle: 'Use the verification link sent to your email address',
resendButton: "Didn't receive a link? Resend",
verified: {
title: 'Successfully signed up',
},
loading: {
title: 'Signing up...',
},
verifiedSwitchTab: {
title: 'Successfully verified email',
subtitle: 'Return to the newly opened tab to continue',
subtitleNewTab: 'Return to previous tab to continue',
},
},
emailCode: {
title: 'Verify your email',
subtitle: 'to continue to {{applicationName}}',
formTitle: 'Verification code',
formSubtitle: 'Enter the verification code sent to your email address',
resendButton: "Didn't receive a code? Resend",
},
phoneCode: {
title: 'Verify your phone',
subtitle: 'to continue to {{applicationName}}',
formTitle: 'Verification code',
formSubtitle: 'Enter the verification code sent to your phone number',
resendButton: "Didn't receive a code? Resend",
},
continue: {
title: 'Fill in missing fields',
subtitle: 'to continue to {{applicationName}}',
actionText: 'Have an account?',
actionLink: 'Sign in',
},
},
If you want to customize multiple entries from the <SignUp />
component, the procedure would resemble the following:
const localization = {
signUp: {
start: {
subtitle: 'to access {{applicationName}}',
},
emailCode: {
subtitle: 'to access {{applicationName}}',
},
},
}
Feedback
Last updated on