Skip to content

Conversation

@jacekradko
Copy link
Member

@jacekradko jacekradko commented Jan 23, 2026

Summary

Refactors the UI loading architecture so users only interact with an opaque ui prop from @clerk/ui. Each SDK internally decides whether to use the bundled UI constructor or load from CDN.

Key Changes

  • Public API: Users pass ui={ui} - the object is opaque
  • Removed clerkUiCtor from public IsomorphicClerkOptions (kept internally in ClerkOptions for SDK use)
  • Added __internal_forceBundledUI escape hatch for SDKs that must bundle the UI
  • Version pinning: CDN loading uses ui.version to pin the UI version

SDK Behavior

SDK Uses Bundled UI? Implementation
Chrome Extension Yes Sets __internal_forceBundledUI: true
React/Next.js No CDN with ui.version pinning
Vue No CDN with ui.version pinning
Astro No CDN with ui.version pinning

Usage

import { ui } from '@clerk/ui';

<ClerkProvider ui={ui}>
  ...
</ClerkProvider>

The ui export is opaque - users just pass it to ClerkProvider without accessing internals. The SDK handles whether to use ui.ctor or load from CDN.

Test plan

  • Build passes
  • Unit tests pass
  • Verify Chrome Extension works with bundled UI
  • Verify React/Next.js loads from CDN with correct version
  • Verify Vue loads from CDN with correct version
  • Verify Astro loads from CDN with correct version

Summary by CodeRabbit

  • New Features

    • ClerkProvider now accepts a new ui prop to pass the @clerk/ui package (enables bundled UI usage).
    • Supports UI version pinning and custom CDN URL via the unified ui configuration.
  • Refactor

    • UI loading/initialization reshaped for consistent wiring of bundled vs CDN UI across integrations.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Jan 23, 2026

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

1 Skipped Deployment
Project Deployment Review Updated (UTC)
clerk-js-sandbox Skipped Skipped Jan 24, 2026 4:46am

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Jan 23, 2026

🦋 Changeset detected

Latest commit: 9774008

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

This PR includes changesets to release 20 packages
Name Type
@clerk/ui Minor
@clerk/react Minor
@clerk/vue Minor
@clerk/astro Minor
@clerk/chrome-extension Minor
@clerk/shared Minor
@clerk/expo Patch
@clerk/nextjs Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/nuxt Patch
@clerk/agent-toolkit Patch
@clerk/backend Patch
@clerk/clerk-js Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/msw Patch
@clerk/testing Patch

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 23, 2026

Open in StackBlitz

@clerk/agent-toolkit

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

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 9774008

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

📝 Walkthrough

Walkthrough

This pull request renames the UI constructor type from ClerkUiConstructor to ClerkUIConstructor and standardizes the global hook name from __internal_ClerkUiCtor to __internal_ClerkUICtor. It replaces the top-level clerkUiCtor option with a nested ui object (containing version, url, ClerkUI, and __internal_forceBundledUI) across packages. The @clerk/ui export now exposes ClerkUI. UI loading was refactored to prefer CDN loading with version pinning unless a bundled UI is forced or provided via ui.ClerkUI.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: replacing clerkUiCtor prop with ui prop across React, Vue, and Astro packages, which is the primary refactor in this PR.

✏️ 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/vue/src/plugin.ts (1)

81-91: Misleading comment on fallback behavior.

The comment states "fall back to clerkUiCtor (deprecated)" but the actual fallback is loading from CDN via loadClerkUiScript, not checking a clerkUiCtor property. Consider updating the comment to accurately reflect the behavior:

-          // Check for ui.ctor first (new API), then fall back to clerkUiCtor (deprecated)
+          // Check for ui.ctor first (bundled UI), then fall back to loading from CDN
🧹 Nitpick comments (1)
packages/astro/src/internal/create-clerk-instance.ts (1)

118-122: Misleading comment: fallback is CDN loading, not clerkUiCtor.

The comment mentions "fall back to clerkUiCtor (deprecated)" but the actual fallback is loading from CDN via loadClerkUiScript. The clerkUiCtor option path was removed from this function.

Suggested fix
-  // Check for ui.ctor first (new API), then fall back to clerkUiCtor (deprecated)
+  // If ui.ctor is provided (bundled UI), use it directly; otherwise load from CDN
   const ctorFromUi = options?.ui?.ctor;
   if (ctorFromUi) {
     return ctorFromUi;
   }

Adds `ui` prop to ClerkProvider for specifying UI metadata.
Each SDK decides whether to use `ui.ctor` based on support level.

- `@clerk/ui` exports only `{ ui }` with version and ctor
- Chrome extension uses `ui.ctor` (verified to work)
- React, Vue, Astro use CDN loading (not verified for bundling yet)
- Omit `clerkUiCtor` from public ClerkProviderProps type
@jacekradko jacekradko force-pushed the jrad/ui-prop-cleanup branch from 431aa50 to c5ff0d1 Compare January 23, 2026 20:05
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/astro/src/internal/create-clerk-instance.ts (1)

111-124: ui.ctor is not being used when provided.

The PR objective states that when ui.ctor is provided, it should be used instead of loading from CDN. However, getClerkUiEntryChunk always loads the UI script from CDN and ignores options.ui?.ctor. This contradicts the JSDoc in packages/astro/src/types.ts (lines 39-43) which states: "When provided with a bundled UI via ui.ctor, it will be used instead of loading from CDN."

Suggested fix to honor ui.ctor when provided
 async function getClerkUiEntryChunk<TUi extends Ui = Ui>(
   options?: AstroClerkCreateInstanceParams<TUi>,
 ): Promise<ClerkUiConstructor> {
+  // Use bundled UI constructor if provided
+  if (options?.ui?.ctor) {
+    return options.ui.ctor;
+  }
+
   await loadClerkUiScript(options);

   if (!window.__internal_ClerkUiCtor) {
     throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
   }

   return window.__internal_ClerkUiCtor;
 }
🤖 Fix all issues with AI agents
In `@packages/vue/src/plugin.ts`:
- Around line 81-87: The code always calls loadClerkUiScript and ignores a
provided bundled constructor; update the clerkUiCtorPromise logic to first check
pluginOptions.ui?.ctor (or options.ui?.ctor) and resolve to that ctor if
present, otherwise call loadClerkUiScript and fall back to
window.__internal_ClerkUiCtor; ensure clerkUiCtorPromise returns the provided
ctor when available, and preserve the existing error throw if neither the
provided ctor nor the downloaded window.__internal_ClerkUiCtor is present.

Comment on lines 81 to 87
const clerkUiCtorPromise = (async () => {
await loadClerkUiScript(options);
if (!window.__internal_ClerkUiCtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}
return window.__internal_ClerkUiCtor;
})();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

ui.ctor is not being used when provided.

Same issue as in the Astro integration: the code always loads the UI from CDN via loadClerkUiScript and ignores pluginOptions.ui?.ctor. This contradicts the documented behavior that bundled UI via ui.ctor should be used instead of CDN loading.

Suggested fix to honor ui.ctor when provided
          const clerkUiCtorPromise = (async () => {
+            // Use bundled UI constructor if provided
+            if (pluginOptions.ui?.ctor) {
+              return pluginOptions.ui.ctor;
+            }
+
             await loadClerkUiScript(options);
             if (!window.__internal_ClerkUiCtor) {
               throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
             }
             return window.__internal_ClerkUiCtor;
           })();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const clerkUiCtorPromise = (async () => {
await loadClerkUiScript(options);
if (!window.__internal_ClerkUiCtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}
return window.__internal_ClerkUiCtor;
})();
const clerkUiCtorPromise = (async () => {
// Use bundled UI constructor if provided
if (pluginOptions.ui?.ctor) {
return pluginOptions.ui.ctor;
}
await loadClerkUiScript(options);
if (!window.__internal_ClerkUiCtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}
return window.__internal_ClerkUiCtor;
})();
🤖 Prompt for AI Agents
In `@packages/vue/src/plugin.ts` around lines 81 - 87, The code always calls
loadClerkUiScript and ignores a provided bundled constructor; update the
clerkUiCtorPromise logic to first check pluginOptions.ui?.ctor (or
options.ui?.ctor) and resolve to that ctor if present, otherwise call
loadClerkUiScript and fall back to window.__internal_ClerkUiCtor; ensure
clerkUiCtorPromise returns the provided ctor when available, and preserve the
existing error throw if neither the provided ctor nor the downloaded
window.__internal_ClerkUiCtor is present.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/chrome-extension/src/react/ClerkProvider.tsx`:
- Around line 38-40: The spread uses an unsafe cast ({...(rest as any)}) to
sneak in clerkUiCtor, hiding a type mismatch; replace this by declaring an
internal extended props type (e.g., InternalClerkProviderProps) that extends
ClerkProviderProps and includes clerkUiCtor with the correct type, update the
component signature to use that internal type, remove the as any cast, and pass
clerkUiCtor={ui.ctor} and Clerk={clerkInstance} with proper typing so TypeScript
enforces compatibility (locate symbols: ClerkProvider.tsx, rest, clerkUiCtor,
ui.ctor, ClerkReactProvider, ClerkProviderProps, clerkInstance).
♻️ Duplicate comments (1)
packages/vue/src/plugin.ts (1)

81-87: ui.ctor is not being used when provided.

Same issue as in the Astro integration: the code always loads the UI from CDN via loadClerkUiScript and ignores pluginOptions.ui?.ctor. This contradicts the documented behavior that bundled UI via ui.ctor should be used instead of CDN loading.

🧹 Nitpick comments (1)
.changeset/shiny-owls-dance.md (1)

10-23: Consider adding migration guidance.

The changeset describes the new ui prop but doesn't mention the deprecation or removal of clerkUiCtor. Since the PR objectives state "Omits clerkUiCtor from public ClerkProviderProps," consider adding explicit migration guidance to help users transition from the old API.

📝 Suggested addition for migration guidance
 Usage:
 ```tsx
 import { ui } from '@clerk/ui';
 
 <ClerkProvider ui={ui}>
   ...
 </ClerkProvider>

+Migration note: The clerkUiCtor prop has been removed from public types. Use the ui prop instead by importing the ui object from @clerk/ui.

</details>

</blockquote></details>

</blockquote></details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/react/src/isomorphicClerk.ts (1)

511-535: Add tests for the new bundled ui.ctor path and CDN fallback.

Line 511 introduces a new early-return path for ui.ctor. I don’t see tests in this PR; please add (or point to) coverage that validates the bundled constructor path and the CDN fallback to prevent regressions.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/astro/src/internal/create-clerk-instance.ts`:
- Around line 111-126: The function getClerkUiEntryChunk always calls
loadClerkUiScript and ignores a bundled UI constructor; update it to first check
options?.ui?.ctor and, if present, return that ClerkUIConstructor directly
instead of loading the CDN script. If ctor is absent, fall back to the current
CDN path (calling loadClerkUiScript with options and returning the resolved
ClerkUIConstructor). Ensure you reference getClerkUiEntryChunk,
options.ui?.ctor, loadClerkUiScript and the ClerkUIConstructor in the change so
the bundled path is honored.
♻️ Duplicate comments (1)
packages/vue/src/plugin.ts (1)

81-92: Honor bundled ui.ctor when provided (currently ignored).

Line 81–92 always load UI from CDN and never use pluginOptions.ui?.ctor, so bundled UI cannot work. This breaks the documented ui.ctor behavior and fails in bundle-only scenarios.

🔧 Proposed fix
-          const ClerkUIPromise = (async () => {
-            await loadClerkUiScript({
-              ...options,
-              clerkUiVersion: pluginOptions.ui?.version,
-              clerkUiUrl: pluginOptions.ui?.url,
-            });
-            if (!window.__internal_ClerkUiCtor) {
-              throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
-            }
-            return window.__internal_ClerkUiCtor;
-          })();
+          const ClerkUIPromise = (async () => {
+            if (pluginOptions.ui?.ctor) {
+              return await pluginOptions.ui.ctor;
+            }
+            await loadClerkUiScript({
+              ...options,
+              clerkUiVersion: pluginOptions.ui?.version,
+              clerkUiUrl: pluginOptions.ui?.url,
+            });
+            if (!window.__internal_ClerkUiCtor) {
+              throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
+            }
+            return window.__internal_ClerkUiCtor;
+          })();

Comment on lines 111 to 126
/**
* Gets the ClerkUI constructor, either from options or by loading the script.
* Returns early if window.__internal_ClerkUiCtor already exists.
* Gets the ClerkUI constructor by loading from CDN with version pinning.
*/
async function getClerkUiEntryChunk<TUi extends Ui = Ui>(
options?: AstroClerkCreateInstanceParams<TUi>,
): Promise<ClerkUiConstructor> {
if (options?.clerkUiCtor) {
return options.clerkUiCtor;
}

await loadClerkUiScript(options);
): Promise<ClerkUIConstructor> {
// Load UI from CDN with version pinning from ui.version
await loadClerkUiScript(
options
? {
...options,
clerkUiVersion: options.ui?.version,
clerkUiUrl: options.ui?.url,
}
: undefined,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Bundled ui.ctor path is missing (doc promises it).

Line 111–126 always load from CDN and ignore options.ui?.ctor, but the public Astro types explicitly state bundled UI should be used when provided. This will break bundle-only setups.

🔧 Proposed fix
 async function getClerkUiEntryChunk<TUi extends Ui = Ui>(
   options?: AstroClerkCreateInstanceParams<TUi>,
 ): Promise<ClerkUIConstructor> {
+  if (options?.ui?.ctor) {
+    return await options.ui.ctor;
+  }
   await loadClerkUiScript(
     options
       ? {
           ...options,
           clerkUiVersion: options.ui?.version,
           clerkUiUrl: options.ui?.url,
         }
       : undefined,
   );
🤖 Prompt for AI Agents
In `@packages/astro/src/internal/create-clerk-instance.ts` around lines 111 - 126,
The function getClerkUiEntryChunk always calls loadClerkUiScript and ignores a
bundled UI constructor; update it to first check options?.ui?.ctor and, if
present, return that ClerkUIConstructor directly instead of loading the CDN
script. If ctor is absent, fall back to the current CDN path (calling
loadClerkUiScript with options and returning the resolved ClerkUIConstructor).
Ensure you reference getClerkUiEntryChunk, options.ui?.ctor, loadClerkUiScript
and the ClerkUIConstructor in the change so the bundled path is honored.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/astro/src/types.ts (1)

17-44: Add tests for the new ui option before merge.

I don’t see test updates covering the new public ui option (bundled vs CDN path). Please add coverage to prevent regressions.

🤖 Fix all issues with AI agents
In `@integration/templates/express-vite/src/client/main.ts`:
- Around line 9-13: The call to clerk.load is passing an incorrect UI
constructor property (ClerkUI: ui.ClerkUI) which is undefined; update the
options passed to clerk.load to use the exported constructor field (ClerkUI:
ui.ctor) so the bundled UI loads correctly — locate the clerk.load(...) call in
main.ts and replace references to ui.ClerkUI with ui.ctor.

Comment on lines 9 to 13
// Use bundled UI via ui.ClerkUI
await clerk.load({
clerkUiCtor: ClerkUi,
ui,
ClerkUI: ui.ClerkUI,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's check what files exist in packages/ui/src
find packages/ui/src -type f -name "*.ts" | head -20

Repository: clerk/javascript

Length of output: 1069


🏁 Script executed:

#!/bin/bash
# Check the main export file
cat -n packages/ui/src/index.ts | head -50

Repository: clerk/javascript

Length of output: 714


🏁 Script executed:

#!/bin/bash
# Search for ClerkUI and ctor exports
rg -n "ClerkUI|ctor" packages/ui/src/ -t ts

Repository: clerk/javascript

Length of output: 50373


🏁 Script executed:

#!/bin/bash
# Check the actual file being imported in the template
cat -n integration/templates/express-vite/src/client/main.ts | head -20

Repository: clerk/javascript

Length of output: 740


🏁 Script executed:

cat -n packages/ui/src/internal/index.ts | grep -A 10 "ClerkUI"

Repository: clerk/javascript

Length of output: 1088


🏁 Script executed:

# Check how clerk.load expects ClerkUI to be provided
rg -n "clerk.load" integration/templates/express-vite/src/client/main.ts -A 5 -B 5

Repository: clerk/javascript

Length of output: 320


🏁 Script executed:

# Check if there are other templates or examples that show correct usage
rg -n "ClerkUI:" integration/templates/ -t ts -l

Repository: clerk/javascript

Length of output: 113


🏁 Script executed:

# Let's verify the exact usage pattern - check if there are comments or docs about how to use ui
rg -n "ctor|ClerkUI" packages/ui/src/index.ts -B 5 -A 2

Repository: clerk/javascript

Length of output: 199


🏁 Script executed:

# Check if there's any adapter or aliasing happening elsewhere
rg -n "ui\.ctor" --type ts integration/ packages/

Repository: clerk/javascript

Length of output: 42


Fix UI constructor mismatch: use ui.ctor instead of ui.ClerkUI.

Line 12 passes ClerkUI: ui.ClerkUI, but @clerk/ui exports ui with a ctor field, not ClerkUI. This will pass undefined and break bundled UI loading. Change to ClerkUI: ui.ctor.

🤖 Prompt for AI Agents
In `@integration/templates/express-vite/src/client/main.ts` around lines 9 - 13,
The call to clerk.load is passing an incorrect UI constructor property (ClerkUI:
ui.ClerkUI) which is undefined; update the options passed to clerk.load to use
the exported constructor field (ClerkUI: ui.ctor) so the bundled UI loads
correctly — locate the clerk.load(...) call in main.ts and replace references to
ui.ClerkUI with ui.ctor.

- Remove top-level ClerkUI from ClerkOptions, now only available via ui.ClerkUI
- SDKs construct ui: { version?, url?, ClerkUI } when loading from CDN
- Fix TypeScript declaration file issues by not spreading branded Ui type
- Update warning function to check ui.version for version pinning detection
The rename commit missed the actual runtime export in packages/ui/src/index.ts.
This fixes the bundled UI scenario where clerk.load({ ui }) expects ui.ClerkUI.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/vue/src/plugin.ts`:
- Around line 81-92: Add unit tests to cover CDN UI loading with version pinning
and custom URL by exercising the ClerkUIPromise path: mock or stub
loadClerkUiScript to capture received options and simulate setting
window.__internal_ClerkUICtor, then assert that loadClerkUiScript was called
with clerkUiVersion equal to pluginOptions.ui?.version and clerkUiUrl equal to
pluginOptions.ui?.url and that ClerkUIPromise resolves to
window.__internal_ClerkUICtor; include tests for (1) version pinning only, (2)
custom URL only, and (3) both combined, using the plugin initialization that
creates ClerkUIPromise.

Comment on lines +81 to +92
// Load UI from CDN with version pinning from ui.version
const ClerkUIPromise = (async () => {
await loadClerkUiScript({
...options,
clerkUiVersion: pluginOptions.ui?.version,
clerkUiUrl: pluginOptions.ui?.url,
});
if (!window.__internal_ClerkUICtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}
return window.__internal_ClerkUICtor;
})();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

git diff --name-only origin/main...HEAD | grep -E '(test|spec)\.(ts|tsx|js|jsx)$|__tests__|\.test\.|\.spec\.'

Repository: clerk/javascript

Length of output: 100


🏁 Script executed:

# Find test files related to Vue plugin
fd -e ts -e tsx -e js -e jsx | grep -E 'vue.*test|vue.*spec|__tests__.*vue'

Repository: clerk/javascript

Length of output: 956


🏁 Script executed:

# Check the structure of the Vue package
find packages/vue -type f \( -name '*.test.*' -o -name '*.spec.*' -o -path '*/__tests__/*' \) | head -20

Repository: clerk/javascript

Length of output: 765


🏁 Script executed:

# Check if there's a test file for plugin.ts
find packages/vue -name 'plugin*.test.*' -o -name 'plugin*.spec.*'

Repository: clerk/javascript

Length of output: 42


🏁 Script executed:

# Look for tests that reference loadClerkUiScript or CDN loading
rg -i 'loadClerkUiScript|clerkUiVersion|clerkUiUrl' packages/vue/src --type ts --type tsx -A 3 -B 3

Repository: clerk/javascript

Length of output: 87


🏁 Script executed:

# Check the full plugin.ts file to understand context
cat -n packages/vue/src/plugin.ts | head -120

Repository: clerk/javascript

Length of output: 4685


🏁 Script executed:

# Check if there are integration tests that might cover plugin loading
rg 'loadClerkUiScript|clerkUiVersion|clerkUiUrl|plugin.ts' packages/vue --type ts -i -l

Repository: clerk/javascript

Length of output: 86


🏁 Script executed:

# Check existing tests to see if they cover plugin initialization
cat packages/vue/src/components/__tests__/ClerkHostRenderer.test.ts | head -50

Repository: clerk/javascript

Length of output: 1335


🏁 Script executed:

# Check if plugin initialization is tested anywhere in Vue package
rg 'clerkPlugin|install|plugin' packages/vue/src -i -l --type ts | grep test

Repository: clerk/javascript

Length of output: 122


🏁 Script executed:

# Check useClerkContext test to see if it covers plugin initialization
cat packages/vue/src/composables/__tests__/useClerkContext.test.ts

Repository: clerk/javascript

Length of output: 1320


🏁 Script executed:

# Check integration tests for Vue plugin
cat integration/tests/vue/components.test.ts | head -100

Repository: clerk/javascript

Length of output: 4110


🏁 Script executed:

# Look for any test that imports or mocks loadClerkUiScript
rg 'loadClerkUiScript|loadClerkJsScript' packages/vue -i --type ts -l -A 5

Repository: clerk/javascript

Length of output: 112


Add unit tests for Vue plugin CDN UI loading with version pinning.

The new clerkUiVersion and clerkUiUrl parameters in the CDN loading path are not covered by existing tests. Add tests to verify the version pinning and custom URL functionality works correctly.

🤖 Prompt for AI Agents
In `@packages/vue/src/plugin.ts` around lines 81 - 92, Add unit tests to cover CDN
UI loading with version pinning and custom URL by exercising the ClerkUIPromise
path: mock or stub loadClerkUiScript to capture received options and simulate
setting window.__internal_ClerkUICtor, then assert that loadClerkUiScript was
called with clerkUiVersion equal to pluginOptions.ui?.version and clerkUiUrl
equal to pluginOptions.ui?.url and that ClerkUIPromise resolves to
window.__internal_ClerkUICtor; include tests for (1) version pinning only, (2)
custom URL only, and (3) both combined, using the plugin initialization that
creates ClerkUIPromise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants