Skip to content

fix(ui): Improve structural CSS warning message format, warn for appearance usage on components#7628

Merged
brkalow merged 9 commits intomainfrom
bryce/warn-customization-without-pinning-2
Feb 3, 2026
Merged

fix(ui): Improve structural CSS warning message format, warn for appearance usage on components#7628
brkalow merged 9 commits intomainfrom
bryce/warn-customization-without-pinning-2

Conversation

@brkalow
Copy link
Member

@brkalow brkalow commented Jan 20, 2026

Description

  • Improve the warning message for structural CSS detection based on feedback.
  • Trigger detection on appearance objects passed directly to components

BEFORE

🔒 Clerk:
[CLERK_W001] Structural CSS detected

Found: 
  -
  -

May break on updates. Pin your version:
  npm install @clerk/ui && import { ui } from '@clerk/ui'
  <ClerkProvider ui={ui} />

https://clerk.com/docs/customization/versioning
(This notice only appears in development)

AFTER

Clerk: Structural CSS detected that may break on updates.

Found:
  -
  -

These selectors depend on the internal DOM structure of Clerk's components, which may change when Clerk deploys component updates.
To prevent breaking changes, install @clerk/ui and pass it to ClerkProvider:

  import { ui } from '@clerk/ui'
  <ClerkProvider ui={ui}>

Learn more: https://clerk.com/docs/reference/components/versioning
(code=structural_css_pin_clerk_ui)

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Development-only warnings now surface when structural CSS customizations are detected without UI pinning, including condensed, bulleted pattern listings for component-level appearance.
  • Tests

    • Added tests for development vs production, pinned vs unpinned UI, missing provider context, idle-timing behavior, and new warning formatting.
  • Chores

    • Minor changelog entry and bundle size thresholds adjusted.

brkalow and others added 3 commits January 20, 2026 13:49
- Clearer title and explanation
- Package manager agnostic install instructions
- Use (code=structural_css_pin_clerk_ui) error code format

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, the structural CSS warning only triggered when ClerkProvider
mounted. This adds checking when individual components mount with their
own appearance prop (e.g., <SignIn appearance={...} />).

- Add warnAboutComponentAppearance() for checking component-level appearance
- Add useWarnAboutCustomizationWithoutPinning hook called from AppearanceProvider
- Hook gracefully handles missing context (e.g., in tests)
- Only runs in development mode

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@brkalow brkalow requested review from dstaley and jacekradko January 20, 2026 23:10
@changeset-bot
Copy link

changeset-bot bot commented Jan 20, 2026

🦋 Changeset detected

Latest commit: fb6cb15

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Feb 3, 2026 2:29pm

Request Review

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 20, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7628

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7628

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7628

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7628

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7628

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7628

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7628

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7628

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7628

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7628

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7628

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7628

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7628

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7628

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7628

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7628

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7628

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7628

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7628

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7628

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7628

commit: fb6cb15

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

Introduces a development-only structural CSS warning flow: adds hook useWarnAboutCustomizationWithoutPinning and calls it from the Appearance provider with appearance to run a deferred check. The hook reads Clerk and Options contexts, stabilizes appearance, defers work via requestIdleCallback with a fallback, skips in production or when contexts are absent, and cleans up on unmount. Adds warnAboutComponentAppearance(appearance, uiPinned) to collect and format up to five detected element patterns as bullet points and emit a one-time warning. Tests cover the hook and utility behavior.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main changes: improving the structural CSS warning message format and adding appearance-level component warnings.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…owser.js

- ui.browser.js: 34KB -> 34.5KB
- ui.legacy.browser.js: 72KB -> 73KB

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@alexcarpenter
Copy link
Member

!snapshot

@clerk-cookie
Copy link
Collaborator

Hey @alexcarpenter - the snapshot version command generated the following package versions:

Package Version
@clerk/agent-toolkit 0.2.9-snapshot.v20260126181919
@clerk/astro 3.0.0-snapshot.v20260126181919
@clerk/backend 3.0.0-snapshot.v20260126181919
@clerk/chrome-extension 3.0.0-snapshot.v20260126181919
@clerk/clerk-js 6.0.0-snapshot.v20260126181919
@clerk/dev-cli 1.0.0-snapshot.v20260126181919
@clerk/expo 3.0.0-snapshot.v20260126181919
@clerk/expo-passkeys 1.0.0-snapshot.v20260126181919
@clerk/express 2.0.0-snapshot.v20260126181919
@clerk/fastify 2.6.9-snapshot.v20260126181919
@clerk/localizations 4.0.0-snapshot.v20260126181919
@clerk/msw 0.0.1-snapshot.v20260126181919
@clerk/nextjs 7.0.0-snapshot.v20260126181919
@clerk/nuxt 2.0.0-snapshot.v20260126181919
@clerk/react 6.0.0-snapshot.v20260126181919
@clerk/react-router 3.0.0-snapshot.v20260126181919
@clerk/shared 4.0.0-snapshot.v20260126181919
@clerk/tanstack-react-start 1.0.0-snapshot.v20260126181919
@clerk/testing 2.0.0-snapshot.v20260126181919
@clerk/ui 1.0.0-snapshot.v20260126181919
@clerk/upgrade 2.0.0-snapshot.v20260126181919
@clerk/vue 2.0.0-snapshot.v20260126181919

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/agent-toolkit

npm i @clerk/agent-toolkit@0.2.9-snapshot.v20260126181919 --save-exact

@clerk/astro

npm i @clerk/astro@3.0.0-snapshot.v20260126181919 --save-exact

@clerk/backend

npm i @clerk/backend@3.0.0-snapshot.v20260126181919 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.0.0-snapshot.v20260126181919 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.0.0-snapshot.v20260126181919 --save-exact

@clerk/dev-cli

npm i @clerk/dev-cli@1.0.0-snapshot.v20260126181919 --save-exact

@clerk/expo

npm i @clerk/expo@3.0.0-snapshot.v20260126181919 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@1.0.0-snapshot.v20260126181919 --save-exact

@clerk/express

npm i @clerk/express@2.0.0-snapshot.v20260126181919 --save-exact

@clerk/fastify

npm i @clerk/fastify@2.6.9-snapshot.v20260126181919 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.0.0-snapshot.v20260126181919 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.1-snapshot.v20260126181919 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.0.0-snapshot.v20260126181919 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@2.0.0-snapshot.v20260126181919 --save-exact

@clerk/react

npm i @clerk/react@6.0.0-snapshot.v20260126181919 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.0.0-snapshot.v20260126181919 --save-exact

@clerk/shared

npm i @clerk/shared@4.0.0-snapshot.v20260126181919 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.0.0-snapshot.v20260126181919 --save-exact

@clerk/testing

npm i @clerk/testing@2.0.0-snapshot.v20260126181919 --save-exact

@clerk/ui

npm i @clerk/ui@1.0.0-snapshot.v20260126181919 --save-exact

@clerk/upgrade

npm i @clerk/upgrade@2.0.0-snapshot.v20260126181919 --save-exact

@clerk/vue

npm i @clerk/vue@2.0.0-snapshot.v20260126181919 --save-exact

Copy link
Member

@alexcarpenter alexcarpenter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outside of the perf review shared in slack, tested in dashboard and working 👍🏼

Copy link
Member

@nikosdouvlis nikosdouvlis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvement to the DX here

});

return () => {
if (typeof cancelIdleCallback === 'function' && typeof handle === 'number') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When requestIdleCallback isn't available, we fall back to setTimeout but the cleanup still calls cancelIdleCallback. Probably fine since the 0ms timeout fires immediately anyway, just wanted to flag it

…utPinning

- Use useDeepEqualMemo to stabilize appearance reference, preventing
  effect re-runs when consumers pass inline objects
- Fix cleanup function to properly handle setTimeout fallback when
  requestIdleCallback is unavailable (Safari < 16.4, Node)
- Extract inline regexes to module-level constants to avoid repeated
  compilation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@brkalow brkalow merged commit c73aa48 into main Feb 3, 2026
38 checks passed
@brkalow brkalow deleted the bryce/warn-customization-without-pinning-2 branch February 3, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants