āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/directory/clerk/clerk-docs/guides/customizing-clerk/appearance-prop/variables ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
Variables prop'
description: Utilize Clerk's variables property in order to adjust the general styles of the component's base theme, like colors, backgrounds, typography.{/* JS file: https://github.com/clerk/javascript/blob/main/packages/types/src/appearance.ts#L399 */}
The variables property is used to adjust the general styles of the component's base theme, like colors, backgrounds, and typography.
The primary color used throughout the components.
CSS variable: --clerk-color-primary
colorDangerstringThe color used for error states.
CSS variable: --clerk-color-danger
colorSuccessstringThe color used for success states.
CSS variable: --clerk-color-success
colorWarningstringThe color used for warning states.
CSS variable: --clerk-color-warning
colorNeutralstringThe color that will be used for all to generate the neutral shades the components use. This option applies to borders, backgrounds for hovered elements, hovered dropdown options.
CSS variable: --clerk-color-neutral
colorForegroundstringThe color used for text.
CSS variable: --clerk-color-foreground
colorPrimaryForegroundstringThe color used for text on the primary background.
CSS variable: --clerk-color-primary-foreground
colorMutedForegroundstringThe color used for secondary text.
CSS variable: --clerk-color-muted-foreground
colorMutedstringThe color used for muted backgrounds.
CSS variable: --clerk-color-muted
colorBackgroundstringThe background color for the card container.
CSS variable: --clerk-color-background
colorInputForegroundstringThe color used for text in input fields.
CSS variable: --clerk-color-input-foreground
colorInputstringThe background color used for input fields.
CSS variable: --clerk-color-input
colorShimmerstringThe color of the avatar shimmer.
CSS variable: --clerk-color-shimmer
colorRingstringThe color of the ring when an interactive element is focused.
CSS variable: --clerk-color-ring
colorShadowstringThe base shadow color used in the components.
CSS variable: --clerk-color-shadow
colorBorderstringThe base border color used in the components.
CSS variable: --clerk-color-border
colorModalBackdropstringThe background color of the modal backdrop.
CSS variable: --clerk-color-modal-backdrop
fontFamilystringThe font family used throughout the components. By default, it is set to inherit.
CSS variable: --clerk-font-family
fontFamilyButtonsstringThe font family used for buttons. By default, it is set to inherit.
CSS variable: --clerk-font-family-buttons
fontSizestring | {xs: string, sm: string, md: string, lg: string, xl: string}The font size used throughout the components. By default, this is set to 0.8125rem.
CSS variable: --clerk-font-size
fontWeight{normal: number, medium: number, semibold: number, bold: number}The font weight used throughout the components. By default, this is set to {normal: 400, medium: 500, semibold: 600, bold: 700}.
CSS variable: --clerk-font-weight
borderRadiusstringThe border radius used throughout the components. By default, this is set to 0.375rem.
CSS variable: --clerk-border-radius
spacingstringThe spacing unit used throughout the components. By default, this is set to 1rem.
CSS variable: --clerk-spacing
</Properties>
The following properties are deprecated as of 2025-07-15 and will be removed in the next major version of Clerk.
colorText (use colorForeground instead)colorTextOnPrimaryBackground (use colorPrimaryForeground instead)colorTextSecondary (use colorMutedForeground instead)spacingUnit (use spacing instead)colorInputText (use colorInputForeground instead)colorInputBackground (use colorInput instead)You can customize Clerk components by passing an object of variables to the variables property of the appearance prop.
[!NOTE browser-compatibility-considerations] Browser Compatibility Considerations
Clerk's theming system uses modern CSS features like
color-mix()and relative color syntax to automatically generate color variations from your base colors. These features require:
color-mix(): Chrome 111+, Firefox 113+, Safari 16.2+- Relative color syntax: Chrome 119+, Firefox 120+, Safari 16.4+
For broader browser support, when using the
variablesprop, use direct color values (e.g.colorPrimary: '#6c47ff') instead of CSS variables or modern color functions.
variables to all Clerk componentsTo customize all Clerk components, pass the variables property to the appearance prop of the <ClerkProvider> component.
In the following example, the primary color is set to blue and the text color is set to black. Because these styles are applied to the <ClerkProvider>, which wraps the entire application, these styles will be applied to all Clerk components that use the primary color and text color.
<Tabs items={["Next.js", "React", "Remix", "Astro", "Vue", "Nuxt"]}> <Tab> <CodeBlockTabs options={["App Router", "Pages Router"]}> ```tsx {{ filename: '/src/app/layout.tsx', mark: [[6, 11]] }} import { ClerkProvider } from '@clerk/nextjs'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider
appearance={{
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
}}
>
<html lang="en">
<body>{children}</body>
</html>
</ClerkProvider>
)
}
```
```tsx {{ filename: '_app.tsx', mark: [[7, 12]] }}
import { ClerkProvider } from '@clerk/nextjs'
import type { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return (
<ClerkProvider
appearance={{
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
}}
>
<Component {...pageProps} />
</ClerkProvider>
)
}
export default MyApp
```
</CodeBlockTabs>
</Tab>
<Tab>
```tsx {{ filename: 'app.tsx', mark: [[13, 18]] }}
import React from 'react'
import './App.css'
import { ClerkProvider } from '@clerk/clerk-react'
if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) {
throw new Error('Missing Publishable Key')
}
const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY
function App() {
return (
<ClerkProvider
appearance={{
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
}}
publishableKey={clerkPubKey}
>
<div>Hello from clerk</div>
</ClerkProvider>
)
}
export default App
```
</Tab>
<Tab>
```tsx {{ filename: 'app/root.tsx', mark: [[35, 40]] }}
// Import ClerkApp
import { ClerkApp } from '@clerk/remix'
import type { MetaFunction, LoaderFunction } from '@remix-run/node'
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react'
import { rootAuthLoader } from '@clerk/remix/ssr.server'
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)
function App() {
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
)
}
export default ClerkApp(App, {
appearance: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
})
```
</Tab>
<Tab>
```js {{ filename: 'astro.config.mjs', mark: [[6, 11]] }}
import clerk from '@clerk/astro'
export default defineConfig({
integrations: [
clerk({
appearance: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
}),
],
})
```
</Tab>
<Tab>
```ts {{ filename: 'src/main.ts', mark: [[7, 12]] }}
import { createApp } from 'vue'
import App from './App.vue'
import { clerkPlugin } from '@clerk/vue'
const app = createApp(App)
app.use(clerkPlugin, {
appearance: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
})
app.mount('#app')
```
</Tab>
<Tab>
```ts {{ filename: 'nuxt.config.ts', mark: [[4, 9]] }}
export default defineNuxtConfig({
modules: ['@clerk/nuxt'],
clerk: {
appearance: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
},
})
```
</Tab>
</Tabs>
variables to all instances of a Clerk componentYou can customize all instances of a Clerk component by passing the component to the appearance prop of the <ClerkProvider>. The appearance prop accepts the name of the Clerk component you want to style as a key.
In the following example, the primary color is set to blue and the text color is set to black for all instances of the <SignIn /> component.
<Tabs items={["Next.js", "React", "Remix", "Astro", "Vue", "Nuxt"]}> <Tab> <CodeBlockTabs options={["App Router", "Pages Router"]}> ```tsx {{ filename: '/src/app/layout.tsx', mark: [[6, 13]] }} import { ClerkProvider } from '@clerk/nextjs'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider
appearance={{
signIn: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
}}
>
<html lang="en">
<body>{children}</body>
</html>
</ClerkProvider>
)
}
```
```tsx {{ filename: '_app.tsx', mark: [[7, 14]] }}
import { ClerkProvider } from '@clerk/nextjs'
import type { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return (
<ClerkProvider
appearance={{
signIn: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
}}
>
<Component {...pageProps} />
</ClerkProvider>
)
}
export default MyApp
```
</CodeBlockTabs>
</Tab>
<Tab>
```tsx {{ filename: 'app.tsx', mark: [[13, 20]] }}
import React from 'react'
import './App.css'
import { ClerkProvider } from '@clerk/clerk-react'
if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) {
throw new Error('Missing Publishable Key')
}
const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY
function App() {
return (
<ClerkProvider
appearance={{
signIn: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
}}
publishableKey={clerkPubKey}
>
<div>Hello from clerk</div>
</ClerkProvider>
)
}
export default App
```
</Tab>
<Tab>
```tsx {{ filename: 'app/root.tsx', mark: [[35, 42]] }}
// Import ClerkApp
import { ClerkApp } from '@clerk/remix'
import type { MetaFunction, LoaderFunction } from '@remix-run/node'
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react'
import { rootAuthLoader } from '@clerk/remix/ssr.server'
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)
function App() {
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
)
}
export default ClerkApp(App, {
appearance: {
signIn: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
},
})
```
</Tab>
<Tab>
```js {{ filename: 'astro.config.mjs', mark: [[6, 13]] }}
import clerk from '@clerk/astro'
export default defineConfig({
integrations: [
clerk({
appearance: {
signIn: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
},
}),
],
})
```
</Tab>
<Tab>
```ts {{ filename: 'src/main.ts', mark: [[7, 14]] }}
import { createApp } from 'vue'
import App from './App.vue'
import { clerkPlugin } from '@clerk/vue'
const app = createApp(App)
app.use(clerkPlugin, {
appearance: {
signIn: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
},
})
app.mount('#app')
```
</Tab>
<Tab>
```ts {{ filename: 'nuxt.config.ts', mark: [[4, 11]] }}
export default defineNuxtConfig({
modules: ['@clerk/nuxt'],
clerk: {
appearance: {
signIn: {
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
},
},
},
})
```
</Tab>
</Tabs>
variables to a single Clerk componentTo customize a single Clerk component, pass the variables property to the appearance prop of the Clerk component.
The following example shows how to customize the <SignIn /> component by setting the primary color to blue and the text color to black.
<Tabs items={["Next.js", "React", "Remix", "Astro", "Vue", "Nuxt"]}> <Tab> <CodeBlockTabs options={["App Router", "Pages Router"]}> ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', mark: [[6, 11]] }} import { SignIn } from '@clerk/nextjs'
export default function Page() {
return (
<SignIn
appearance={{
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
}}
/>
)
}
```
```tsx {{ filename: '/pages/sign-in/[[...index]].tsx', mark: [[5, 10]] }}
import { SignIn } from '@clerk/nextjs'
const SignInPage = () => (
<SignIn
appearance={{
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
}}
/>
)
export default SignInPage
```
</CodeBlockTabs>
</Tab>
<Tab>
```tsx {{ filename: '/src/sign-in/[[...index]].tsx', mark: [[5, 10]] }}
import { SignIn } from '@clerk/clerk-react'
const SignInPage = () => (
<SignIn
appearance={{
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
}}
/>
)
export default SignInPage
```
</Tab>
<Tab>
```tsx {{ filename: 'app/routes/sign-in/$.tsx', mark: [[8, 13]] }}
import { SignIn } from '@clerk/remix'
export default function SignInPage() {
return (
<div style={{ border: '2px solid blue', padding: '2rem' }}>
<h1>Sign In route</h1>
<SignIn
appearance={{
variables: {
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
},
}}
/>
</div>
)
}
```
</Tab>
<Tab>
```astro {{ filename: 'pages/sign-in.astro', mark: [[7, 10]] }}
---
import { SignIn } from '@clerk/astro/components'
---
<SignIn
appearance={{
colorPrimary: '#0000ff', // blue
colorForeground: '#000000', // black
}}
/>
```
</Tab>
<Tab>
```vue {{ filename: 'src/pages/sign-in.vue', mark: [6] }}
<script setup lang="ts">
import { SignIn } from '@clerk/vue'
</script>
<template>
<SignIn :appearance="{ variables: { colorPrimary: '#0000ff', colorForeground: '#000000' } }" />
</template>
```
</Tab>
<Tab>
```vue {{ filename: 'pages/sign-in.vue', mark: [6] }}
<script setup lang="ts">
// Components are automatically imported
</script>
<template>
<SignIn :appearance="{ colorPrimary: '#0000ff', colorForeground: '#000000' }" />
</template>
```
</Tab>
</Tabs>
[!WARNING] Please consider this approach with browser compatibility in mind, as it may not work in older browsers. See Browser Compatibility Considerations for details.
You can also use CSS variables to customize the appearance of Clerk components. This approach is particularly useful when:
The following example demonstrates how to use CSS variables to customize the appearance of Clerk components, but for maximum browser compatibility, it's recommended to use direct color values instead.
<CodeBlockTabs options={["global.css", "layout.tsx"]}>
:root {
--brand-primary: oklch(49.1% 0.27 292.581);
}
@media (prefers-color-scheme: dark) {
:root {
--brand-primary: oklch(54.1% 0.281 293.009);
}
}
import { ClerkProvider } from '@clerk/nextjs'
import './global.css'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider
appearance={{
variables: {
colorPrimary: 'var(--brand-primary)',
},
}}
>
<html lang="en">
<body>{children}</body>
</html>
</ClerkProvider>
)
}
</CodeBlockTabs>
Clerk exposes native CSS variables if you would prefer to define variables directly in your application's stylesheet. All variables exposed through the appearance object are also exposed as CSS variables; see the properties section for a list of the available variables.
The Clerk CSS variables are prefixed with clerk- and are in kebab-case:
:root {
--clerk-color-primary: #0000ff; /* colorPrimary */
--clerk-color-foreground: #000000; /* colorForeground */
}
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā