diff --git a/docs/_partials/customizing-clerk-info.mdx b/docs/_partials/customizing-clerk-info.mdx new file mode 100644 index 0000000000..ba7a02de8f --- /dev/null +++ b/docs/_partials/customizing-clerk-info.mdx @@ -0,0 +1 @@ +It is passed as a parameter to the [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) prop, which is available wherever you initialize the Clerk integration. For most SDKs, this is done via the [``](/docs/reference/components/clerk-provider) component. For other SDKs, it's configured through the SDK's Clerk integration or plugin. diff --git a/docs/_partials/nextjs/nextjs-app-router-preface.mdx b/docs/_partials/nextjs/nextjs-app-router-preface.mdx new file mode 100644 index 0000000000..332184e9ef --- /dev/null +++ b/docs/_partials/nextjs/nextjs-app-router-preface.mdx @@ -0,0 +1 @@ +This is written for Next.js App Router but can be adapted for any React-based SDK. diff --git a/docs/guides/customizing-clerk/adding-items/organization-profile.mdx b/docs/guides/customizing-clerk/adding-items/organization-profile.mdx index 421f4f3970..6096beeae3 100644 --- a/docs/guides/customizing-clerk/adding-items/organization-profile.mdx +++ b/docs/guides/customizing-clerk/adding-items/organization-profile.mdx @@ -50,9 +50,11 @@ To add a custom page to the `` component, use the ` +The following example demonstrates two ways that you can render content in a custom page: as a component or as a direct child. + + - The following example demonstrates two ways that you can render content in a custom page: as a component or as a direct child. + ", "Dedicated page"]}> ```tsx {{ filename: 'app/components/Header.tsx' }} @@ -151,6 +153,58 @@ To add a custom page to the `` component, use the ` + + ", "Dedicated page"]}> + ```astro {{ filename: 'pages/index.astro' }} + --- + import { OrganizationSwitcher } from '@clerk/astro/components' + --- + +
+ + + + + +
+

Custom page

+

This is the content of the custom page.

+
+
+
+
+ ``` + + ```astro {{ filename: 'pages/organization-profile.astro' }} + --- + import { OrganizationProfile } from '@clerk/astro/components' + --- + + + + + + +
+

Custom page

+

This is the content of the custom page.

+
+
+
+ ``` +
+
+ To add custom pages to the `` component using the [JavaScript SDK](/docs/reference/javascript/overview), pass the `customPages` property to the `mountOrganizationProfile()` or `openOrganizationProfile()` method, as shown in the following example: @@ -288,8 +342,10 @@ To add an external link to the `` navigation sidenav, use The following example adds a custom link to the `` sidenav that navigates to the homepage. - + + + ", "Dedicated page"]}> ```tsx {{ filename: 'app/components/Header.tsx' }} 'use client' @@ -343,6 +399,84 @@ The following example adds a custom link to the `` sidena + + ", "Dedicated page"]}> + ```astro {{ filename: 'pages/index.astro' }} + --- + import { OrganizationSwitcher } from '@clerk/astro/components' + --- + +
+ + + + + + + +
+ ``` + + ```astro {{ filename: 'pages/organization-profile.astro' }} + --- + import { OrganizationProfile } from '@clerk/astro/components' + --- + + + + + + + + + ``` +
+
+ + + To add custom pages to the `` component using the [JavaScript SDK](/docs/reference/javascript/overview), pass the `customPages` property to the `mountOrganizationProfile()` or `openOrganizationProfile()` method, as shown in the following example: + + ```js {{ filename: 'main.js' }} + import { Clerk } from '@clerk/clerk-js' + + const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY + + const clerk = new Clerk(pubKey) + await clerk.load() + + document.getElementById('app').innerHTML = ` +
+ ` + + const orgProfileDiv = document.getElementById('organization-profile') + + clerk.openOrganizationProfile(orgProfileDiv, { + customPages: [ + { + url: '/', + label: 'Homepage', + mountIcon: (el) => { + el.innerHTML = '🌐' + }, + unmountIcon: (el) => { + el.innerHTML = '' + }, + }, + ], + }) + ``` +
+ ", "Dedicated page"]}> ```vue {{ filename: 'App.vue' }} @@ -394,8 +528,10 @@ Note that when reordering default routes, the first item in the navigation siden The following example adds a custom page as the first item in the sidenav, followed by a custom link to the homepage, and then the default members and general pages. - + + + ", "Dedicated Page"]}> ```tsx {{ filename: 'app/components/Header.tsx' }} 'use client' @@ -481,6 +617,82 @@ The following example adds a custom page as the first item in the sidenav, follo + + ", "Dedicated page"]}> + ```astro {{ filename: 'pages/index.astro' }} + --- + import { OrganizationSwitcher } from '@clerk/astro/components' + --- + +
+ + + + + +
+

Custom page

+

This is the content of the custom page.

+
+
+ + + + + + + +
+
+ ``` + + ```astro {{ filename: 'pages/organization-profile.astro' }} + --- + import { OrganizationProfile } from '@clerk/astro/components' + --- + + + + + + +
+

Custom page

+

This is the content of the custom page.

+
+
+ + + + + + + +
+ ``` +
+
+ ", "Dedicated page"]}> ```vue {{ filename: 'App.vue' }} diff --git a/docs/guides/customizing-clerk/adding-items/user-button.mdx b/docs/guides/customizing-clerk/adding-items/user-button.mdx index 7e8ea2e736..dbd5614a02 100644 --- a/docs/guides/customizing-clerk/adding-items/user-button.mdx +++ b/docs/guides/customizing-clerk/adding-items/user-button.mdx @@ -56,6 +56,8 @@ The following example adds an "Open chat" action to the `` compone + + ```tsx {{ filename: '/app/page.tsx' }} 'use client' @@ -203,8 +205,10 @@ The following example adds an "Open chat" action to the `` compone The following example adds an "Open chat" action to the `` component, as well as a [custom page](/docs/guides/customizing-clerk/adding-items/user-profile) titled "Help". When a user selects the ``, there will be "Open chat" and "Help" menu items. - + + + ```tsx {{ filename: '/app/page.tsx' }} 'use client' @@ -283,6 +287,61 @@ The following example adds an "Open chat" action to the `` compone ``` + + To add custom pages to the `` component using the [JavaScript SDK](/docs/reference/javascript/overview), pass the `customPages` property to the `mountUserProfile()` method, as shown in the following example: + + ```js {{ filename: 'main.js' }} + import { Clerk } from '@clerk/clerk-js' + + const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY + + const clerk = new Clerk(pubKey) + await clerk.load() + + document.getElementById('app').innerHTML = ` +
+ ` + + const userProfileDiv = document.getElementById('user-profile') + + clerk.mountUserProfile(userProfileDiv, { + customMenuItems: [ + { + label: 'Help modal', + onClick: () => { + alert('Open modal') // your custom event + }, + mountIcon: (el) => { + el.innerHTML = '👤' + }, + unmountIcon: (el) => {}, + }, + ], + customPages: [ + { + url: '/help', + label: 'Help', + mountIcon: (el) => { + el.innerHTML = '👤' + }, + unmountIcon: (el) => { + el.innerHTML = '' + }, + mount: (el) => { + el.innerHTML = ` +

Help Page

+

This is the custom help page

+ ` + }, + unmount: (el) => { + el.innerHTML = '' + }, + }, + ], + }) + ``` +
+ ```vue {{ filename: 'App.vue' }} + + + ``` +
+ + + + In Vue, pass the `captcha` property to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/vue/overview) integration. + + ```ts {{ filename: 'src/main.ts', mark: [[8, 12]] }} + import { createApp } from 'vue' + import App from './App.vue' + import { clerkPlugin } from '@clerk/vue' + + const app = createApp(App) + app.use(clerkPlugin, { + appearance: { + captcha: { + theme: 'dark', + size: 'flexible', + language: 'es-ES', + }, + }, + }) + app.mount('#app') + ``` + + + + In Nuxt, pass the `captcha` property to the `appearance` prop of the [`defineNuxtConfig()`](/docs/reference/nuxt/clerk-middleware) integration. + + ```ts {{ filename: 'nuxt.config.ts', mark: [[5, 9]] }} + export default defineNuxtConfig({ + modules: ['@clerk/nuxt'], + clerk: { appearance: { captcha: { theme: 'dark', @@ -186,8 +175,28 @@ The `captcha` property can be used to change the appearance of the CAPTCHA widge language: 'es-ES', }, }, - }) - app.mount('#app') - ``` -
-
+ }, + }) + ``` + + + + In Fastify, pass the `captcha` property to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/fastify/clerk-plugin) integration. + + ```ts {{ filename: 'src/main.ts', mark: [[8, 12]] }} + import Fastify from 'fastify' + import { clerkPlugin } from '@clerk/fastify' + + const fastify = Fastify({ logger: true }) + + fastify.register(clerkPlugin, { + appearance: { + captcha: { + theme: 'dark', + size: 'flexible', + language: 'es-ES', + }, + }, + }) + ``` + diff --git a/docs/guides/customizing-clerk/appearance-prop/layout.mdx b/docs/guides/customizing-clerk/appearance-prop/layout.mdx index 6f5ae53030..3af84826f3 100644 --- a/docs/guides/customizing-clerk/appearance-prop/layout.mdx +++ b/docs/guides/customizing-clerk/appearance-prop/layout.mdx @@ -7,6 +7,8 @@ description: Utilize Clerk's layout prop in order to change the layout of the `](/docs/reference/components/authentication/sign-in) and [``](/docs/reference/components/authentication/sign-up) components, as well as set important links to your support, terms, and privacy pages. + + ## Properties @@ -95,53 +97,61 @@ The `layout` property can be used to change the layout of the [``](/doc ## Usage - - - ```tsx {{ prettier: false, filename: 'app.tsx' }} - import { ClerkProvider } from '@clerk/nextjs'; - - - {/* ... */} - ; - ``` - - - - ```js {{ filename: 'astro.config.mjs' }} - import clerk from '@clerk/astro' - - export default defineConfig({ - integrations: [ - clerk({ - appearance: { - layout: { - socialButtonsPlacement: 'bottom', - socialButtonsVariant: 'iconButton', - termsPageUrl: 'https://clerk.com/terms', - }, + + For React-based SDKs, pass the `layout` property to the `appearance` prop of the [``](/docs/reference/components/clerk-provider) component. + + ```tsx {{ mark: [[3, 7]] }} + + {/* ... */} + + ``` + + + + In Astro, pass the `layout` property to the `appearance` prop of the [`clerk()`](/docs/reference/astro/overview) integration. + + ```js {{ filename: 'astro.config.mjs', mark: [[7, 11]] }} + import clerk from '@clerk/astro' + + export default defineConfig({ + integrations: [ + clerk({ + appearance: { + layout: { + socialButtonsPlacement: 'bottom', + socialButtonsVariant: 'iconButton', + termsPageUrl: 'https://clerk.com/terms', }, - }), - ], - }) - ``` - + }, + }), + ], + }) + ``` + - - ```ts {{ filename: 'src/main.ts' }} - import { createApp } from 'vue' - import App from './App.vue' - import { clerkPlugin } from '@clerk/vue' + + In JavaScript, pass the `layout` property to the `appearance` prop of the [`clerk.load()`](/docs/reference/javascript/clerk#load) method. - const app = createApp(App) - app.use(clerkPlugin, { + Use the following tabs to view the code necessary for each file. + + + ```js {{ filename: 'main.js', mark: [[8, 12]], collapsible: true }} + import { Clerk } from '@clerk/clerk-js' + + const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY + + const clerk = new Clerk(clerkPubKey) + await clerk.load({ appearance: { layout: { socialButtonsPlacement: 'bottom', @@ -150,24 +160,102 @@ The `layout` property can be used to change the layout of the [``](/doc }, }, }) - app.mount('#app') + + if (clerk.isSignedIn) { + document.getElementById('app').innerHTML = ` +
+ ` + + const userButtonDiv = document.getElementById('user-button') + + clerk.mountUserButton(userButtonDiv) + } else { + document.getElementById('app').innerHTML = ` +
+ ` + + const signInDiv = document.getElementById('sign-in') + + clerk.mountSignIn(signInDiv) + } ``` -
- - ```ts {{ filename: 'nuxt.config.ts' }} - export default defineNuxtConfig({ - modules: ['@clerk/nuxt'], - clerk: { - appearance: { - layout: { - socialButtonsPlacement: 'bottom', - socialButtonsVariant: 'iconButton', - termsPageUrl: 'https://clerk.com/terms', - }, + ```html {{ filename: 'index.html' }} + + + + + + + Clerk + JavaScript App + + +
+ + + + ``` +
+ + + + In Vue, pass the `layout` property to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/vue/overview) integration. + + ```ts {{ filename: 'src/main.ts', mark: [[8, 12]] }} + import { createApp } from 'vue' + import App from './App.vue' + import { clerkPlugin } from '@clerk/vue' + + const app = createApp(App) + app.use(clerkPlugin, { + appearance: { + layout: { + socialButtonsPlacement: 'bottom', + socialButtonsVariant: 'iconButton', + termsPageUrl: 'https://clerk.com/terms', + }, + }, + }) + app.mount('#app') + ``` + + + + In Nuxt, pass the `layout` property to the `appearance` prop of the [`defineNuxtConfig()`](/docs/reference/nuxt/clerk-middleware) integration. + + ```ts {{ filename: 'nuxt.config.ts', mark: [[5, 9]] }} + export default defineNuxtConfig({ + modules: ['@clerk/nuxt'], + clerk: { + appearance: { + layout: { + socialButtonsPlacement: 'bottom', + socialButtonsVariant: 'iconButton', + termsPageUrl: 'https://clerk.com/terms', }, }, - }) - ``` -
-
+ }, + }) + ``` + + + + In Fastify, pass the `layout` property to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/fastify/clerk-plugin) integration. + + ```ts {{ filename: 'src/main.ts', mark: [[8, 12]] }} + import Fastify from 'fastify' + import { clerkPlugin } from '@clerk/fastify' + + const fastify = Fastify({ logger: true }) + + fastify.register(clerkPlugin, { + appearance: { + layout: { + socialButtonsPlacement: 'bottom', + socialButtonsVariant: 'iconButton', + termsPageUrl: 'https://clerk.com/terms', + }, + }, + }) + ``` + diff --git a/docs/guides/customizing-clerk/appearance-prop/overview.mdx b/docs/guides/customizing-clerk/appearance-prop/overview.mdx index 3821332ede..c1af7dd7bb 100644 --- a/docs/guides/customizing-clerk/appearance-prop/overview.mdx +++ b/docs/guides/customizing-clerk/appearance-prop/overview.mdx @@ -7,7 +7,7 @@ description: Utilize Clerk's appearance property in order to share styles across Customizing the appearance of Clerk components is a powerful way to make your application look and feel unique. Clerk provides a way to customize the appearance of its components using the `appearance` prop. -The `appearance` prop can be applied to [``](/docs/reference/components/clerk-provider) to share styles across every component, or individually to any of the Clerk components. +The `appearance` prop is available wherever you initialize the Clerk integration. For most SDKs, it's applied to the [``](/docs/reference/components/clerk-provider) component. For other SDKs, it's configured through the SDK's Clerk integration or plugin. You can use it to share styles across every component, or individually to any of the Clerk components. This applies to all of the React-based packages, like [Next.js](/docs/nextjs/getting-started/quickstart), as well as [the pure JavaScript ClerkJS package](/docs/reference/javascript/overview). @@ -138,22 +138,44 @@ Remove the `cl-` prefix from a class and use it as the key for a new object in t The following example shows how to style the primary button in a `` component with custom CSS classes: -```tsx {{ mark: [4] }} - + ```tsx {{ mark: [4] }} + + ``` + + + + ```vue {{ mark: [4, 10] }} + + + + ``` + #### Use Tailwind classes to style Clerk components -To use Tailwind CSS v4, you must set the `cssLayerName` property to ensure that Tailwind's utility styles are applied after Clerk's styles. It's recommended to add this to the `` that wraps your app so that it's applied to all Clerk components, as shown in the following example. The example names the layer `clerk` but you can name it anything you want. +To use Tailwind CSS v4, you must set the `cssLayerName` property to ensure that Tailwind's utility styles are applied after Clerk's styles. It's recommended to add this to the `` or the SDK's Clerk integration that wraps your app so that it's applied to all Clerk components, as shown in the following example. The example names the layer `clerk` but you can name it anything you want. - + + The following example is written for Next.js App Router but can be adapted for any React-based SDK. + ```tsx {{ mark: ["cssLayerName: 'clerk'"] }} import { ClerkProvider } from '@clerk/nextjs' @@ -244,6 +266,27 @@ To use Tailwind CSS v4, you must set the `cssLayerName` property to ensure that + + + ```tsx {{ mark: ["cssLayerName: 'clerk'"] }} + export default defineNuxtConfig({ + modules: ['@clerk/nuxt', '@nuxtjs/tailwindcss'], + css: ['@/assets/css/global.css'], + clerk: { + appearance: { + cssLayerName: 'clerk', + }, + }, + }) + ``` + + ```css {{ mark: ['clerk'] }} + @layer theme, base, clerk, components, utilities; + @import 'tailwindcss'; + ``` + + + ```html {{ mark: ["cssLayerName: 'clerk'"] }} @@ -268,15 +311,35 @@ To use Tailwind CSS v4, you must set the `cssLayerName` property to ensure that Then, you can use Tailwind's classes to style the elements of the Clerk component. The following example shows how to use Tailwind classes to style the primary button in a `` component: -```tsx {{ mark: [4] }} - + ```tsx {{ mark: [4] }} + + ``` + + + + ```vue {{ mark: [4, 10] }} + + + + ``` + #### Use CSS modules to style Clerk components @@ -293,56 +356,43 @@ Create your module file and add the CSS you want to apply, as shown in the follo Then you can apply this by importing the file and using the classes whenever required: - - - - ```tsx {{ filename: 'app/layout.tsx', mark: [[9, 15]] }} - import styles from '../styles/SignIn.module.css' - import { ClerkProvider, SignIn } from '@clerk/nextjs' - - export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - - - - - - - ) - } - ``` - - ```tsx {{ filename: 'app.tsx', mark: [[8, 14]] }} - import styles from '../styles/SignIn.module.css' - import { ClerkProvider, SignIn } from '@clerk/nextjs' - import type { AppProps } from 'next/app' - - function MyApp({ pageProps }: AppProps) { - return ( - - - - ) - } + + ```tsx {{ mark: [1, 8] }} + import styles from '../styles/SignIn.module.css' + + export default function CustomSignIn() { + return ( + + ) + } + ``` + + + + ```vue {{ mark: [2, 6, 12] }} + - export default MyApp - ``` - - - + + ``` + ### Use inline CSS objects to style Clerk components @@ -350,69 +400,49 @@ You can style the elements of a Clerk component with inline CSS objects. The following example shows how to style the primary button in a `` component with an inline CSS object: - - - - ```tsx {{ filename: 'app/layout.tsx', mark: [[9, 22]] }} - import styles from '../styles/SignIn.module.css' - import { ClerkProvider, SignIn } from '@clerk/nextjs' - - export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - - - - - - - ) - } - ``` - - ```tsx {{ filename: 'app.tsx', mark: [[7, 20]] }} - import { ClerkProvider, SignIn } from '@clerk/nextjs' - import type { AppProps } from 'next/app' - - function MyApp({ pageProps }: AppProps) { - return ( - - - - ) - } + + ```tsx {{ mark: [[4, 11]] }} + + ``` + + + + ```vue {{ mark: [[4, 11], 17] }} + - export default MyApp - ``` - - - + + ``` + ## Next steps @@ -424,7 +454,7 @@ Here are a few resources you can utilize to customize your Clerk components furt --- - - [prebuilt themes](/docs/guides/customizing-clerk/appearance-prop/themes) + - [Prebuilt themes](/docs/guides/customizing-clerk/appearance-prop/themes) - Explore the prebuilt themes that you can use to quickly style your Clerk components. --- diff --git a/docs/guides/customizing-clerk/appearance-prop/themes.mdx b/docs/guides/customizing-clerk/appearance-prop/themes.mdx index af12f0384d..67787c80bd 100644 --- a/docs/guides/customizing-clerk/appearance-prop/themes.mdx +++ b/docs/guides/customizing-clerk/appearance-prop/themes.mdx @@ -85,197 +85,167 @@ To use the simple theme, set `theme` to `simple`: 1. To get started, install the `@clerk/themes` package. - - ```bash {{ filename: 'terminal' }} - npm install @clerk/themes - ``` - - ```bash {{ filename: 'terminal' }} - yarn add @clerk/themes - ``` - - ```bash {{ filename: 'terminal' }} - pnpm add @clerk/themes - ``` - - ```bash {{ filename: 'terminal' }} - bun add @clerk/themes - ``` - + ```npm {{ filename: 'terminal' }} + npm install @clerk/themes + ``` + 1. To use a theme, import it from `@clerk/themes` and pass it to the `appearance` prop of a Clerk component. ### Apply a theme to all Clerk components -To apply a theme to all Clerk components, pass the `appearance` prop to the [``](/docs/reference/components/clerk-provider) component. The `appearance` prop accepts the property `theme`, which can be set to a theme. +The `theme` property is used to apply a theme to all Clerk components. + + In the following example, the "Dark" theme is applied to all Clerk components. - - - - ```tsx {{ filename: '/src/app/layout.tsx', mark: [2, [7, 9]] }} - import { ClerkProvider } from '@clerk/nextjs' - import { dark } from '@clerk/themes' - - export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - - {children} - - - ) - } - ``` - - ```tsx {{ filename: '_app.tsx', mark: [2, 8, 9, 10] }} - import { ClerkProvider } from '@clerk/nextjs' - import { dark } from '@clerk/themes' - import type { AppProps } from 'next/app' - - function MyApp({ Component, pageProps }: AppProps) { - return ( - - - - ) - } - - export default MyApp - ``` - - +#### Example - - ```tsx {{ filename: 'app.tsx', mark: [3, [14, 16]] }} - import React from 'react' - import './App.css' - import { dark } from '@clerk/themes' - 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 + + For React-based SDKs, pass the `theme` property to the `appearance` prop of the [``](/docs/reference/components/clerk-provider) component. + + ```tsx {{ prettier: false, mark: [1, [4, 6]] }} + import { dark } from '@clerk/themes' + + + {/* ... */} + + ``` + + + + In Astro, pass the `theme` property to the `appearance` prop of the [`clerk()`](/docs/reference/astro/overview) integration. + + ```js {{ filename: 'astro.config.mjs', mark: [2, [7, 9]] }} + import clerk from '@clerk/astro' + import { dark } from '@clerk/themes' + + export default defineConfig({ + integrations: [ + clerk({ + appearance: { + theme: dark, + }, + }), + ], + }) + ``` + - function App() { - return ( - -
Hello from clerk
-
- ) - } + + In JavaScript, pass the `theme` property to the `appearance` prop of the [`clerk.load()`](/docs/reference/javascript/clerk#load) method. - export default App - ``` -
+ Use the following tabs to view the code necessary for each file. - - ```js {{ filename: 'astro.config.mjs', mark: [2, [7, 9]] }} - import clerk from '@clerk/astro' + + ```js {{ filename: 'main.js', mark: [2, [8, 10]], collapsible: true }} + import { Clerk } from '@clerk/clerk-js' import { dark } from '@clerk/themes' - export default defineConfig({ - integrations: [ - clerk({ - appearance: { - theme: dark, - }, - }), - ], - }) - ``` - + const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY - - ```tsx {{ filename: 'app/root.tsx', mark: [3, [36, 38]] }} - // Import ClerkApp - import { ClerkApp } from '@clerk/remix' - import { dark } from '@clerk/themes' - import type { MetaFunction, LoaderFunction } from '@remix-run/node' + const clerk = new Clerk(clerkPubKey) + await clerk.load({ + appearance: { + theme: dark, + }, + }) - import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' + if (clerk.isSignedIn) { + document.getElementById('app').innerHTML = ` +
+ ` - import { rootAuthLoader } from '@clerk/remix/ssr.server' + const userButtonDiv = document.getElementById('user-button') - export const meta: MetaFunction = () => ({ - charset: 'utf-8', - title: 'New Remix App', - viewport: 'width=device-width,initial-scale=1', - }) + clerk.mountUserButton(userButtonDiv) + } else { + document.getElementById('app').innerHTML = ` +
+ ` - export const loader: LoaderFunction = (args) => rootAuthLoader(args) + const signInDiv = document.getElementById('sign-in') - function App() { - return ( - - - - - - - - - - - - - ) + clerk.mountSignIn(signInDiv) } + ``` - export default ClerkApp(App, { + ```html {{ filename: 'index.html' }} + + + + + + + Clerk + JavaScript App + + +
+ + + + ``` +
+ + + + In Vue, pass the `theme` property to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/vue/overview) integration. + + ```ts {{ filename: 'src/main.ts', mark: [4, [8, 10]] }} + import { createApp } from 'vue' + import App from './App.vue' + import { clerkPlugin } from '@clerk/vue' + import { dark } from '@clerk/themes' + + const app = createApp(App) + app.use(clerkPlugin, { + appearance: { + theme: dark, + }, + }) + app.mount('#app') + ``` + + + + In Nuxt, pass the `theme` property to the `appearance` prop of the [`defineNuxtConfig()`](/docs/reference/nuxt/clerk-middleware) integration. + + ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 8]] }} + import { dark } from '@clerk/themes' + + export default defineNuxtConfig({ + modules: ['@clerk/nuxt'], + clerk: { appearance: { theme: dark, }, - }) - ``` -
+ }, + }) + ``` + - - ```ts {{ filename: 'src/main.ts', mark: [4, [8, 10]] }} - import { createApp } from 'vue' - import App from './App.vue' - import { clerkPlugin } from '@clerk/vue' - import { dark } from '@clerk/themes' + + In Fastify, pass the `theme` property to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/fastify/clerk-plugin) integration. - const app = createApp(App) - app.use(clerkPlugin, { - appearance: { - theme: dark, - }, - }) - app.mount('#app') - ``` - + ```ts {{ filename: 'src/main.ts', mark: [[8, 12]] }} + import Fastify from 'fastify' + import { clerkPlugin } from '@clerk/fastify' - - ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 8]] }} - import { dark } from '@clerk/themes' + const fastify = Fastify({ logger: true }) - export default defineNuxtConfig({ - modules: ['@clerk/nuxt'], - clerk: { - appearance: { - theme: dark, - }, - }, - }) - ``` - -
+ fastify.register(clerkPlugin, { + appearance: { + theme: dark, + }, + }) + ``` + ### Apply multiple themes @@ -283,411 +253,341 @@ You can also stack themes by passing an array of themes to the `theme` property In the following example, the "Dark" theme is applied first, then the "Neobrutalism" theme is applied on top of it. - - - - ```tsx {{ filename: '/src/app/layout.tsx', mark: [2, [7, 9]] }} - import { ClerkProvider } from '@clerk/nextjs' - import { dark, neobrutalism } from '@clerk/themes' - - export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - - {children} - - - ) - } - ``` - - ```tsx {{ filename: '_app.tsx', mark: [2, [8, 10]] }} - import { ClerkProvider, SignIn } from '@clerk/nextjs' - import { dark, neobrutalism } from '@clerk/themes' - import type { AppProps } from 'next/app' - - function MyApp({ Component, pageProps }: AppProps) { - return ( - - - - ) - } - - export default MyApp - ``` - - +#### Example - - ```tsx {{ filename: 'app.tsx', mark: [3, [14, 16]] }} - import React from 'react' - import './App.css' - import { dark, neobrutalism } from '@clerk/themes' - 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 + + For React-based SDKs, pass the `theme` property to the `appearance` prop of the [``](/docs/reference/components/clerk-provider) component. + + ```tsx {{ prettier: false, mark: [1, [4, 6]] }} + import { dark, neobrutalism } from '@clerk/themes' + + + {/* ... */} + + ``` + + + + In Astro, pass the `theme` property to the `appearance` prop of the [`clerk()`](/docs/reference/astro/overview) integration. + + ```js {{ filename: 'astro.config.mjs', mark: [2, [7, 9]] }} + import clerk from '@clerk/astro' + import { dark, neobrutalism } from '@clerk/themes' + + export default defineConfig({ + integrations: [ + clerk({ + appearance: { + theme: [dark, neobrutalism], + }, + }), + ], + }) + ``` + - function App() { - return ( - -
Hello from clerk
-
- ) - } + + In JavaScript, pass the `theme` property to the `appearance` prop of the [`clerk.load()`](/docs/reference/javascript/clerk#load) method. - export default App - ``` -
+ Use the following tabs to view the code necessary for each file. - - ```js {{ filename: 'astro.config.mjs', mark: [2, [7, 9]] }} - import clerk from '@clerk/astro' + + ```js {{ filename: 'main.js', mark: [2, [8, 10]], collapsible: true }} + import { Clerk } from '@clerk/clerk-js' import { dark, neobrutalism } from '@clerk/themes' - export default defineConfig({ - integrations: [ - clerk({ - appearance: { - theme: [dark, neobrutalism], - }, - }), - ], - }) - ``` - + const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY - - ```tsx {{ filename: 'app/root.tsx', mark: [3, [36, 38]] }} - // Import ClerkApp - import { ClerkApp } from '@clerk/remix' - import { dark, neobrutalism } from '@clerk/themes' - import type { MetaFunction, LoaderFunction } from '@remix-run/node' + const clerk = new Clerk(clerkPubKey) + await clerk.load({ + appearance: { + theme: [dark, neobrutalism], + }, + }) - import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' + if (clerk.isSignedIn) { + document.getElementById('app').innerHTML = ` +
+ ` - import { rootAuthLoader } from '@clerk/remix/ssr.server' + const userButtonDiv = document.getElementById('user-button') - export const meta: MetaFunction = () => ({ - charset: 'utf-8', - title: 'New Remix App', - viewport: 'width=device-width,initial-scale=1', - }) + clerk.mountUserButton(userButtonDiv) + } else { + document.getElementById('app').innerHTML = ` +
+ ` - export const loader: LoaderFunction = (args) => rootAuthLoader(args) + const signInDiv = document.getElementById('sign-in') - function App() { - return ( - - - - - - - - - - - - - ) + clerk.mountSignIn(signInDiv) } + ``` - export default ClerkApp(App, { + ```html {{ filename: 'index.html' }} + + + + + + + Clerk + JavaScript App + + +
+ + + + ``` + + + + + In Vue, pass the `theme` property to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/vue/overview) integration. + + ```ts {{ filename: 'src/main.ts', mark: [4, [8, 10]] }} + import { createApp } from 'vue' + import App from './App.vue' + import { clerkPlugin } from '@clerk/vue' + import { dark, neobrutalism } from '@clerk/themes' + + const app = createApp(App) + app.use(clerkPlugin, { + appearance: { + theme: [dark, neobrutalism], + }, + }) + app.mount('#app') + ``` + + + + In Nuxt, pass the `theme` property to the `appearance` prop of the [`defineNuxtConfig()`](/docs/reference/nuxt/clerk-middleware) integration. + + ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 8]] }} + import { dark, neobrutalism } from '@clerk/themes' + + export default defineNuxtConfig({ + modules: ['@clerk/nuxt'], + clerk: { appearance: { theme: [dark, neobrutalism], }, - }) - ``` -
+ }, + }) + ``` + - - ```ts {{ filename: 'src/main.ts', mark: [4, [8, 10]] }} - import { createApp } from 'vue' - import App from './App.vue' - import { clerkPlugin } from '@clerk/vue' - import { dark, neobrutalism } from '@clerk/themes' + + In Fastify, pass the `theme` property to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/fastify/clerk-plugin) integration. - const app = createApp(App) - app.use(clerkPlugin, { - appearance: { - theme: [dark, neobrutalism], - }, - }) - app.mount('#app') - ``` - + ```ts {{ filename: 'src/main.ts', mark: [[8, 12]] }} + import Fastify from 'fastify' + import { clerkPlugin } from '@clerk/fastify' - - ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 8]] }} - import { dark, neobrutalism } from '@clerk/themes' + const fastify = Fastify({ logger: true }) - export default defineNuxtConfig({ - modules: ['@clerk/nuxt'], - clerk: { - appearance: { - theme: [dark, neobrutalism], - }, - }, - }) - ``` - -
+ fastify.register(clerkPlugin, { + appearance: { + theme: [dark, neobrutalism], + }, + }) + ``` + ### Apply a theme to all instances of a Clerk component -You can apply a theme to all instances of a Clerk component by passing the component to the `appearance` prop of the ``. The `appearance` prop accepts the name of the Clerk component you want to style as a key. +To apply a theme to all instances of a Clerk component, you can pass the component itself to the `appearance` prop. In the following example, the "Neobrutalism" theme is applied to all instances of the [``](/docs/reference/components/authentication/sign-in) component. - - - - ```tsx {{ filename: '/src/app/layout.tsx', mark: [2, [7, 10]] }} - import { ClerkProvider } from '@clerk/nextjs' - import { dark, neobrutalism } from '@clerk/themes' - - export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - - {children} - - - ) - } - ``` - - ```tsx {{ filename: '_app.tsx', mark: [2, [8, 11]] }} - import { ClerkProvider, SignIn } from '@clerk/nextjs' - import { dark } from '@clerk/themes' - import type { AppProps } from 'next/app' - - function MyApp({ Component, pageProps }: AppProps) { - return ( - - - - ) - } - - export default MyApp - ``` - - +#### Example - - ```tsx {{ filename: 'app.tsx', mark: [3, [14, 17]] }} - import React from 'react' - import './App.css' - import { dark } from '@clerk/themes' - import { ClerkProvider } from '@clerk/clerk-react' + + For React-based SDKs, pass the `theme` and `signIn` properties to the `appearance` prop of the [``](/docs/reference/components/clerk-provider) component. + + ```tsx {{ prettier: false, mark: [1, [4, 7]] }} + import { dark, neobrutalism } from '@clerk/themes' + + + {/* ... */} + + ``` + + + + In Astro, pass the `theme` and `signIn` properties to the `appearance` prop of the [`clerk()`](/docs/reference/astro/overview) integration. + + ```js {{ filename: 'astro.config.mjs', mark: [2, [7, 10]] }} + import clerk from '@clerk/astro' + import { dark, neobrutalism } from '@clerk/themes' + + export default defineConfig({ + integrations: [ + clerk({ + appearance: { + theme: dark, + signIn: { theme: neobrutalism }, + }, + }), + ], + }) + ``` + - if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) { - throw new Error('Missing Publishable Key') - } - const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY + + In JavaScript, pass the `theme` and `signIn` properties to the `appearance` prop of the [`clerk.load()`](/docs/reference/javascript/clerk#load) method. - function App() { - return ( - -
Hello from clerk
-
- ) - } + Use the following tabs to view the code necessary for each file. - export default App - ``` -
+ + ```js {{ filename: 'main.js', mark: [2, [8, 11]], collapsible: true }} + import { Clerk } from '@clerk/clerk-js' + import { dark, neobrutalism } from '@clerk/themes' - - ```js {{ filename: 'astro.config.mjs', mark: [2, [7, 10]] }} - import clerk from '@clerk/astro' - import { dark } from '@clerk/themes' + const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY - export default defineConfig({ - integrations: [ - clerk({ - appearance: { - theme: dark, - signIn: { theme: neobrutalism }, - }, - }), - ], + const clerk = new Clerk(clerkPubKey) + await clerk.load({ + appearance: { + theme: dark, + signIn: { theme: neobrutalism }, + }, }) - ``` - - - ```tsx {{ filename: 'app/root.tsx', mark: [3, [36, 39]] }} - // Import ClerkApp - import { ClerkApp } from '@clerk/remix' - import { dark } from '@clerk/themes' - import type { MetaFunction, LoaderFunction } from '@remix-run/node' + if (clerk.isSignedIn) { + document.getElementById('app').innerHTML = ` +
+ ` - import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' + const userButtonDiv = document.getElementById('user-button') - 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', - }) + clerk.mountUserButton(userButtonDiv) + } else { + document.getElementById('app').innerHTML = ` +
+ ` - export const loader: LoaderFunction = (args) => rootAuthLoader(args) + const signInDiv = document.getElementById('sign-in') - function App() { - return ( - - - - - - - - - - - - - ) + clerk.mountSignIn(signInDiv) } - - export default ClerkApp(App, { - appearance: { - theme: dark, - signIn: { theme: neobrutalism }, - }, - }) ``` -
- - ```ts {{ filename: 'src/main.ts', mark: [4, [8, 11]] }} - import { createApp } from 'vue' - import App from './App.vue' - import { clerkPlugin } from '@clerk/vue' - import { dark, neobrutalism } from '@clerk/themes' - - const app = createApp(App) - app.use(clerkPlugin, { + ```html {{ filename: 'index.html' }} + + + + + + + Clerk + JavaScript App + + +
+ + + + ``` +
+ + + + In Vue, pass the `theme` and `signIn` properties to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/vue/overview) integration. + + ```ts {{ filename: 'src/main.ts', mark: [4, [8, 11]] }} + import { createApp } from 'vue' + import App from './App.vue' + import { clerkPlugin } from '@clerk/vue' + import { dark, neobrutalism } from '@clerk/themes' + + const app = createApp(App) + app.use(clerkPlugin, { + appearance: { + theme: dark, + signIn: { theme: neobrutalism }, + }, + }) + app.mount('#app') + ``` + + + + In Nuxt, pass the `theme` and `signIn` properties to the `appearance` prop of the [`defineNuxtConfig()`](/docs/reference/nuxt/clerk-middleware) integration. + + ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 9]] }} + import { dark, neobrutalism } from '@clerk/themes' + + export default defineNuxtConfig({ + modules: ['@clerk/nuxt'], + clerk: { appearance: { theme: dark, signIn: { theme: neobrutalism }, }, - }) - app.mount('#app') - ``` -
- - - ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 9]] }} - import { dark, neobrutalism } from '@clerk/themes' - - export default defineNuxtConfig({ - modules: ['@clerk/nuxt'], - clerk: { - appearance: { - theme: dark, - signIn: { theme: neobrutalism }, - }, - }, - }) - ``` - -
+ }, + }) + ``` + + + + In Fastify, pass the `theme` and `signIn` properties to the `appearance` prop of the [`clerkPlugin()`](/docs/reference/fastify/clerk-plugin) integration. + + ```ts {{ filename: 'src/main.ts', mark: [[8, 12]] }} + import Fastify from 'fastify' + import { clerkPlugin } from '@clerk/fastify' + import { dark, neobrutalism } from '@clerk/themes' + + const fastify = Fastify({ logger: true }) + + fastify.register(clerkPlugin, { + appearance: { + theme: dark, + signIn: { theme: neobrutalism }, + }, + }) + ``` + ### Apply a theme to a single Clerk component To apply a theme to a single Clerk component, pass the `appearance` prop to the component. The `appearance` prop accepts the property `theme`, which can be set to a theme. - + - - ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', mark: [2, [7, 9]] }} - import { SignIn } from '@clerk/nextjs' - import { dark } from '@clerk/themes' - - export default function Page() { - return ( - - ) - } - ``` - - ```tsx {{ filename: '/pages/sign-in/[[...index]].tsx', mark: [2, [6, 8]] }} - import { SignIn } from '@clerk/nextjs' - import { dark } from '@clerk/themes' - - const SignInPage = () => ( + The following example is written for Next.js App Router but can be adapted for any React-based SDK. + + ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', mark: [2, [6, 10]] }} + import { SignIn } from '@clerk/nextjs' + import { dark } from '@clerk/themes' + + export default function Page() { + return ( ) - - export default SignInPage - ``` - - - - - ```tsx {{ filename: '/src/sign-in/[[...index]].tsx', mark: [2, [6, 8]] }} - import { SignIn } from '@clerk/clerk-react' - import { dark } from '@clerk/themes' - - const SignInPage = () => ( - - ) - - export default SignInPage + } ``` - ```astro {{ filename: 'pages/sign-in.astro', mark: [3, [9, 11]] }} + ```astro {{ filename: 'pages/sign-in.astro', mark: [3, [7, 9]] }} --- import { SignIn } from '@clerk/astro/components' import { dark } from '@clerk/themes' @@ -702,29 +602,9 @@ To apply a theme to a single Clerk component, pass the `appearance` prop to the - ```tsx {{ filename: 'app/routes/sign-in/$.tsx', mark: [2, [9, 11]] }} - import { SignIn } from '@clerk/remix' - import { dark } from '@clerk/themes' - - export default function SignInPage() { - return ( -
-

Sign In route

- -
- ) - } - ``` -
- - - ```vue {{ filename: 'src/pages/sign-in.vue' }} + ```vue {{ filename: 'pages/sign-in.vue', mark: [3, 7] }} @@ -735,10 +615,9 @@ To apply a theme to a single Clerk component, pass the `appearance` prop to the - ```vue {{ filename: 'pages/sign-in.vue' }} + ```vue {{ filename: 'pages/sign-in.vue', mark: [6] }}