Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .agent/rules/guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ In development, `client/src/shared/lib/billing/local-plan-override.ts` lets deve
These existing deviations are accepted — do not auto-fix unless explicitly tasked:

- `features/settings/ui/theme-switch-button.tsx` imports from `@/app/providers/theme-provider` — intentional FSD upward import (provider coupling)
- `features/subscription/add-subscription` imports `BrandfetchPicker` from `features/brandfetch` — cross-slice import, accepted (picker is feature-level and used by only one consumer)
- `features/category/ai-generator` cross-imports `features/brandfetch` and uses a deep path into `features/category/manage-categories/ui/emoji-picker`
- `server/src/domains/subscription/subscriptionService.ts` imports `{ db }` directly — some orchestration queries bypass the repository layer

Expand Down Expand Up @@ -208,7 +209,7 @@ These existing deviations are accepted — do not auto-fix unless explicitly tas
| ----------------------------------------------------------------- | ------------------------------------------ |
| `client/src/app/routes/routeTree.gen.ts` | TanStack Router Vite plugin |
| `client/src/shared/lib/i18n/**` | Paraglide (`bun --cwd client run prepare`) |
| `CLAUDE.md`, `.agent/rules/guidelines.md`, `.junie/guidelines.md` | `bun run guidelines:sync` |
| `CLAUDE.md`, `.agent/rules/guidelines.md` | `bun run guidelines:sync` |
| `**/dist/**`, `**/.turbo/**` | Build tools |

Edit source inputs and rerun the appropriate tool instead of hand-editing these.
Expand Down Expand Up @@ -237,7 +238,6 @@ Run the narrowest relevant checks first, then escalate for cross-workspace impac
- Canonical source: `AGENTS.md` (this file).
- Generated mirrors:
- `.agent/rules/guidelines.md`
- `.junie/guidelines.md`
- `CLAUDE.md`
- Do not hand-edit generated mirrors.
- Use:
Expand Down
24 changes: 24 additions & 0 deletions .agents/skills/add-i18n-key/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: add-i18n-key
description: Add a new Paraglide i18n message key to both uk and en locale files, then recompile
disable-model-invocation: true
---

# Add i18n Key

Usage: `/add-i18n-key <key> "<ukrainian text>" "<english text>"`

## Steps

1. Add the key to `client/messages/uk.json` (Ukrainian — base locale, alphabetical order)
2. Add the same key to `client/messages/en.json` (English)
3. Run `bun run --cwd client prepare` to recompile Paraglide output
4. Confirm the compiled key appears in `client/src/shared/lib/i18n/messages.js`

## Rules

- Keys use camelCase
- Ukrainian is the source locale — always provide it even when English is the target
- Never edit anything under `client/src/shared/lib/i18n/` — it is generated
- If the key already exists, report a conflict instead of overwriting
- Maintain alphabetical key order within each JSON file
14 changes: 0 additions & 14 deletions .agents/skills/clerk-custom-ui/.claude-plugin/plugin.json

This file was deleted.

175 changes: 128 additions & 47 deletions .agents/skills/clerk-custom-ui/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,61 @@
---
name: clerk-custom-ui
description: Customize Clerk component appearance - themes, layout, colors, fonts, CSS. Use for appearance styling, visual customization, branding.
description: Custom authentication flows and component appearance - hooks (useSignIn,
useSignUp), themes, colors, fonts, CSS. Use for custom sign-in/sign-up flows, appearance
styling, visual customization, branding.
allowed-tools: WebFetch
license: MIT
metadata:
author: clerk
version: "1.0.0"
version: 2.3.0
---

# Component Customization
# Custom UI

> **Prerequisite**: Ensure `ClerkProvider` wraps your app. See `setup/`.
> **Prerequisite**: Ensure `ClerkProvider` wraps your app. See `clerk-setup` skill.
>
> **Version**: Check `package.json` for the SDK version — see `clerk` skill for the version table. This determines which custom flow references to use below.

## Component Customization Options
This skill covers two areas:
1. **Custom authentication flows** — build your own sign-in/sign-up UI with hooks
2. **Appearance customization** — theme, style, and brand Clerk's pre-built components

| Task | Documentation |
| ---------------------------------- | ----------------------------------------------------------------------------------------- |
| Appearance prop overview | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/overview |
| Layout (structure, logo, buttons) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/layout |
| Themes (pre-built dark/light) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/themes |
| Variables (colors, fonts, spacing) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/variables |
| CAPTCHA configuration | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/captcha |
| Bring your own CSS | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/bring-your-own-css |
## What Do You Need?

## Appearance Pattern
| Task | Reference |
|------|-----------|
| Custom sign-in (Core 2 / LTS) | core-2/custom-sign-in.md |
| Custom sign-up (Core 2 / LTS) | core-2/custom-sign-up.md |
| Custom sign-in (Current SDK v7+) | core-3/custom-sign-in.md |
| Custom sign-up (Current SDK v7+) | core-3/custom-sign-up.md |
| Show component pattern (Current SDK) | core-3/show-component.md |

## Custom Flow References

| Task | Core 2 | Current |
|------|--------|---------|
| Custom sign-in (useSignIn) | `core-2/custom-sign-in.md` | `core-3/custom-sign-in.md` |
| Custom sign-up (useSignUp) | `core-2/custom-sign-up.md` | `core-3/custom-sign-up.md` |
| `<Show>` component | *(use `<SignedIn>`, `<SignedOut>`, `<Protect>`)* | `core-3/show-component.md` |

---

## Appearance Customization

Appearance customization applies to both Core 2 and the current SDK.

### Component Customization Options

| Task | Documentation |
|------|---------------|
| Appearance prop overview | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/overview |
| Options (structure, logo, buttons) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/layout |
| Themes (pre-built dark/light) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/themes |
| Variables (colors, fonts, spacing) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/variables |
| CAPTCHA configuration | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/captcha |
| Bring your own CSS | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/bring-your-own-css |

### Appearance Pattern

```typescript
<SignIn
Expand All @@ -32,63 +64,112 @@ metadata:
colorPrimary: '#0000ff',
borderRadius: '0.5rem',
},
layout: {
options: {
logoImageUrl: '/logo.png',
socialButtonsVariant: 'iconButton',
},
}}
/>
```

> **Core 2 ONLY (skip if current SDK):** The `options` property was named `layout`. Use `layout: { logoImageUrl: '...', socialButtonsVariant: '...' }` instead of `options`.

### variables (colors, typography, borders)

| Property | Description |
| ----------------- | ----------------------------------- |
| `colorPrimary` | Primary color throughout |
| `colorBackground` | Background color |
| `borderRadius` | Border radius (default: `0.375rem`) |
| Property | Description |
|----------|-------------|
| `colorPrimary` | Primary color throughout |
| `colorBackground` | Background color |
| `borderRadius` | Border radius (default: `0.375rem`) |

**Opacity change:** `colorRing` and `colorModalBackdrop` now render at full opacity. Use explicit `rgba()` values if you need transparency.

> **Core 2 ONLY (skip if current SDK):** `colorRing` and `colorModalBackdrop` rendered at 15% opacity by default.

### layout (structure, logo, social buttons)
### options (structure, logo, social buttons)

| Property | Description |
| ------------------------ | --------------------------------------------- |
| `logoImageUrl` | URL to custom logo |
| `socialButtonsVariant` | `'blockButton'` \| `'iconButton'` \| `'auto'` |
| `socialButtonsPlacement` | `'top'` \| `'bottom'` |
| Property | Description |
|----------|-------------|
| `logoImageUrl` | URL to custom logo |
| `socialButtonsVariant` | `'blockButton'` \| `'iconButton'` \| `'auto'` |
| `socialButtonsPlacement` | `'top'` \| `'bottom'` |
| `showOptionalFields` | Show optional fields (default: `false`) |

## shadcn Theme
> **Core 2 ONLY (skip if current SDK):** This property is called `layout`, not `options`. Also, `showOptionalFields` defaulted to `true`.

**If the project has `components.json`** (shadcn/ui installed), use the shadcn theme:
### Themes

Install themes from `@clerk/ui`:

```bash
npm install @clerk/ui
```

```typescript
import { shadcn } from '@clerk/themes'
import { dark } from '@clerk/ui/themes'

<ClerkProvider
appearance={{
theme: shadcn,
}}
/>
<ClerkProvider appearance={{ theme: dark }} />
```

Also import shadcn CSS in your global.css:
> **Core 2 ONLY (skip if current SDK):** Themes are imported from `@clerk/themes` (install `@clerk/themes` instead of `@clerk/ui`). Example: `import { dark } from '@clerk/themes'`.

**Theme stacking** — pass an array where the last theme takes precedence:

```typescript
import { dark, neobrutalism } from '@clerk/ui/themes'

<ClerkProvider appearance={{ theme: [dark, neobrutalism] }} />
```

**CSS `color-scheme` support** — the default theme respects the CSS `color-scheme` property for automatic light/dark mode toggling.

**Available themes:** `dark`, `neobrutalism`, `shadcn`, `simple`

#### shadcn Theme

> **IMPORTANT:** If the project has `components.json` (shadcn/ui installed), ALWAYS apply the shadcn theme as the FIRST customization step. This ensures Clerk components visually match the existing shadcn design system. Skip this only if the user explicitly requests a different theme.

**If the project uses shadcn/ui** (check for `components.json` in the project root), **always use the shadcn theme**:

```typescript
import { shadcn } from '@clerk/ui/themes'

<ClerkProvider appearance={{ theme: shadcn }} />
```

Also import shadcn CSS in your global styles:
```css
@import "tailwindcss";
@import "@clerk/themes/shadcn.css";
@import 'tailwindcss';
@import '@clerk/ui/themes/shadcn.css';
```

> **Core 2 ONLY (skip if current SDK):** Import from `@clerk/themes` and `@clerk/themes/shadcn.css`:
> ```typescript
> import { shadcn } from '@clerk/themes'
> ```
> ```css
> @import '@clerk/themes/shadcn.css';
> ```

## Workflow

1. Identify customization needs (colors, layout, theme, CSS)
2. WebFetch the appropriate documentation from table above
3. Follow official code examples from the docs
4. Apply appearance prop to your Clerk components
1. Identify customization needs (custom flow or appearance)
2. For custom flows: check SDK version → read appropriate `core-2/` or `core-3/` reference
3. For appearance: WebFetch the appropriate documentation from table above
4. Apply appearance prop to your Clerk components or build custom flow with hooks

## Common Pitfalls

| Issue | Solution |
| -------------------- | -------------------------------------------------------------------- |
| Colors not applying | Use `colorPrimary` not `primaryColor` |
| Logo not showing | Put `logoImageUrl` inside `layout: {}` |
| Social buttons wrong | Add `socialButtonsVariant: 'iconButton'` in `layout` |
| Styling not working | Use appearance prop, not direct CSS (unless with bring-your-own-css) |
| Issue | Solution |
|-------|----------|
| Colors not applying | Use `colorPrimary` not `primaryColor` |
| Logo not showing | Put `logoImageUrl` inside `options: {}` (or `layout: {}` in Core 2) |
| Social buttons wrong | Add `socialButtonsVariant: 'iconButton'` in `options` (or `layout` in Core 2) |
| Styling not working | Use appearance prop, not direct CSS (unless with bring-your-own-css) |
| Hook returns different shape | Check SDK version — Core 2 and current have completely different `useSignIn`/`useSignUp` APIs |

## See Also

- `clerk-setup` - Initial Clerk install
- `clerk-nextjs-patterns` - Next.js patterns
- `clerk-orgs` - B2B organizations
Loading
Loading