-
Notifications
You must be signed in to change notification settings - Fork 435
feat(ui): Add unified ui prop with RSC support via conditional exports #7664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jacekradko
wants to merge
48
commits into
main
Choose a base branch
from
jrad/ui-prop-cleanup
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+832
−269
Open
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
c5ff0d1
feat(react,vue,astro): Add ui prop for version metadata
jacekradko d8370e0
chore: add changeset for ui prop
jacekradko 67fdc89
refactor: use ui prop instead of clerkUiCtor in chrome-extension
jacekradko 2399eff
refactor: remove clerkUiCtor from public API, add __internal_forceBun…
jacekradko 89bb1ff
chore: update changeset description
jacekradko ccac639
refactor: rename clerkUiCtor to ClerkUI and ClerkUiConstructor to Cle…
jacekradko cf2a354
refactor: rename __internal_ClerkUiCtor to __internal_ClerkUICtor
jacekradko 1d2c8cf
chore: simplify changeset
jacekradko 8f705a8
refactor: rename ui.ctor to ui.ClerkUI
jacekradko 478a0b3
Merge branch 'main' into jrad/ui-prop-cleanup
jacekradko 9517d40
refactor: move ClerkUI inside ui object in ClerkOptions
jacekradko 890cd43
fix: rename ctor to ClerkUI in ui export
jacekradko 7f7665f
chore: fix formatting
jacekradko a3014de
chore: fix es-ES.ts formatting
jacekradko 9774008
fix(astro): Remove unnecessary eslint-disable directive
jacekradko e81f20a
test(vue): add unit tests for CDN UI loading with version pinning
jacekradko d3c96f3
fix(astro): honor bundled UI constructor in getClerkUiEntryChunk
jacekradko aa0c84b
fix(astro): preserve clerkUiUrl fallback in loadClerkUiScript call
jacekradko 64ff3dc
fix: standardize casing for clerkUIUrl and clerkUIVersion properties
jacekradko 76d7c96
fix(vue): preserve clerkUIUrl fallback when ui.url is not set
jacekradko c0d3b6f
fix(vue): use type cast for clerkUIUrl/clerkUIVersion fallback
jacekradko 61655b1
fix: update integration templates to use clerkUIUrl casing
jacekradko 978a0d8
Merge branch 'main' into jrad/ui-prop-cleanup
jacekradko 18a45b8
test(react-router): Add ClerkProvider clerkUIUrl prop tests
jacekradko a9f4cca
fix(react): Use bundled ClerkUI by default, add __internal_preferCDN …
jacekradko 08064ce
fix(react): Await getClerkUiEntryChunk to ensure ClerkUI is resolved
jacekradko f44ff91
Merge branch 'main' into jrad/ui-prop-cleanup
jacekradko aaecdf7
fix(integration): Wait for Clerk to load before signOut in component …
jacekradko b9a490f
test(react): Add unit tests for bundled vs CDN UI loading
jacekradko 21895c2
Merge main into jrad/ui-prop-cleanup
jacekradko 68a17c9
fix(vue): Handle ui prop in clerkPlugin and fix test mocks
jacekradko 35eaeab
feat(react): Support bundled UI via ui.ClerkUI prop
jacekradko a77ede7
refactor(react,vue): Remove version/url from ui prop, require ClerkUI
jacekradko 4e339ca
fix(vue): Use clerkUICtor option instead of ui.ClerkUI for clerk.load()
jacekradko f9c063b
Merge branch 'main' into jrad/ui-prop-cleanup
jacekradko 6c4d6fe
feat(ui,react): Add react-server conditional export for RSC support
jacekradko 512942c
test(e2e): Add integration test for bundled UI with react-server cond…
jacekradko 208a1ac
test(ui): add snapshot tests for ui export signature
jacekradko 04b6512
Merge branch 'main' into jrad/ui-prop-cleanup
jacekradko 6a161e0
fix(nextjs): skip UI CDN preload when ui prop is passed
jacekradko d5234f7
fix(chrome-extension): use ui prop instead of clerkUICtor
jacekradko a87e669
Merge branch 'main' into jrad/ui-prop-cleanup
jacekradko 41bc6f4
fix(integration): isolate @clerk/ui to bundled-UI-specific test only
jacekradko 2803a6e
fix(astro): support bundled UI via ui prop in getClerkUIEntryChunk
jacekradko d12dcaf
Merge branch 'main' into jrad/ui-prop-cleanup
jacekradko 8bd8934
refactor(shared,ui,clerk-js,react,vue,astro): replace clerkUICtor wit…
jacekradko 955d1ea
fix(vue): fix formatting in plugin.ts
jacekradko f8a8f2e
fix(react): externalize @clerk/ui/entry to prevent bundling into dist
jacekradko File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| --- | ||
| '@clerk/ui': minor | ||
| '@clerk/react': minor | ||
| '@clerk/vue': minor | ||
| '@clerk/astro': minor | ||
| '@clerk/chrome-extension': minor | ||
| '@clerk/shared': minor | ||
| --- | ||
|
|
||
| Add `ui` prop to ClerkProvider for passing `@clerk/ui` | ||
|
|
||
| Usage: | ||
| ```tsx | ||
| import { ui } from '@clerk/ui'; | ||
|
|
||
| <ClerkProvider ui={ui}> | ||
| ... | ||
| </ClerkProvider> | ||
| ``` | ||
|
|
||
| **Migration note**: If you were previously using the internal `clerkUiCtor` prop, migrate to the new `ui` prop by importing `ui` from `@clerk/ui`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
packages/astro/src/internal/__tests__/create-clerk-instance.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; | ||
|
|
||
| const mockLoadClerkUIScript = vi.fn(); | ||
| const mockLoadClerkJSScript = vi.fn(); | ||
|
|
||
| vi.mock('@clerk/shared/loadClerkJsScript', () => ({ | ||
| loadClerkJSScript: (...args: unknown[]) => mockLoadClerkJSScript(...args), | ||
| loadClerkUIScript: (...args: unknown[]) => mockLoadClerkUIScript(...args), | ||
| setClerkJSLoadingErrorPackageName: vi.fn(), | ||
| })); | ||
|
|
||
| // Mock nanostores | ||
| vi.mock('../../stores/external', () => ({ | ||
| $clerkStore: { notify: vi.fn() }, | ||
| })); | ||
|
|
||
| vi.mock('../../stores/internal', () => ({ | ||
| $clerk: { get: vi.fn(), set: vi.fn() }, | ||
| $csrState: { setKey: vi.fn() }, | ||
| })); | ||
|
|
||
| vi.mock('../invoke-clerk-astro-js-functions', () => ({ | ||
| invokeClerkAstroJSFunctions: vi.fn(), | ||
| })); | ||
|
|
||
| vi.mock('../mount-clerk-astro-js-components', () => ({ | ||
| mountAllClerkAstroJSComponents: vi.fn(), | ||
| })); | ||
|
|
||
| const mockClerkUICtor = vi.fn(); | ||
|
|
||
| describe('getClerkUIEntryChunk', () => { | ||
| beforeEach(() => { | ||
| vi.clearAllMocks(); | ||
| vi.resetModules(); | ||
| (window as any).__internal_ClerkUICtor = undefined; | ||
| (window as any).Clerk = undefined; | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| (window as any).__internal_ClerkUICtor = undefined; | ||
| (window as any).Clerk = undefined; | ||
| }); | ||
|
|
||
| it('preserves clerkUIUrl from options', async () => { | ||
| mockLoadClerkUIScript.mockImplementation(async () => { | ||
| (window as any).__internal_ClerkUICtor = mockClerkUICtor; | ||
| return null; | ||
| }); | ||
|
|
||
| mockLoadClerkJSScript.mockImplementation(async () => { | ||
| (window as any).Clerk = { | ||
| load: vi.fn().mockResolvedValue(undefined), | ||
| addListener: vi.fn(), | ||
| }; | ||
| return null; | ||
| }); | ||
|
|
||
| // Dynamically import to get fresh module with mocks | ||
| const { createClerkInstance } = await import('../create-clerk-instance'); | ||
|
|
||
| // Call createClerkInstance with clerkUIUrl | ||
| await createClerkInstance({ | ||
| publishableKey: 'pk_test_xxx', | ||
| clerkUIUrl: 'https://custom.selfhosted.example.com/ui.js', | ||
| }); | ||
|
|
||
| expect(mockLoadClerkUIScript).toHaveBeenCalled(); | ||
| const loadClerkUIScriptCall = mockLoadClerkUIScript.mock.calls[0]?.[0] as Record<string, unknown>; | ||
| expect(loadClerkUIScriptCall?.clerkUIUrl).toBe('https://custom.selfhosted.example.com/ui.js'); | ||
| }); | ||
|
|
||
| it('does not set clerkUIUrl when not provided', async () => { | ||
| mockLoadClerkUIScript.mockImplementation(async () => { | ||
| (window as any).__internal_ClerkUICtor = mockClerkUICtor; | ||
| return null; | ||
| }); | ||
|
|
||
| mockLoadClerkJSScript.mockImplementation(async () => { | ||
| (window as any).Clerk = { | ||
| load: vi.fn().mockResolvedValue(undefined), | ||
| addListener: vi.fn(), | ||
| }; | ||
| return null; | ||
| }); | ||
|
|
||
| const { createClerkInstance } = await import('../create-clerk-instance'); | ||
|
|
||
| await createClerkInstance({ | ||
| publishableKey: 'pk_test_xxx', | ||
| }); | ||
|
|
||
| expect(mockLoadClerkUIScript).toHaveBeenCalled(); | ||
| const loadClerkUIScriptCall = mockLoadClerkUIScript.mock.calls[0]?.[0] as Record<string, unknown>; | ||
| expect(loadClerkUIScriptCall?.clerkUIUrl).toBeUndefined(); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the Astro integration support the
uiprop already or is this planned? I thinkgetClerkUIEntryChunkfor Astro doesn't check forui.ClerkUIlike React and Vue doThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch — just pushed a fix in 2803a6e. Added
ui.ClerkUIsupport to Astro'sgetClerkUIEntryChunkand theuiprop toAstroClerkIntegrationParams, matching what React and Vue already do.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed! Thanks