Skip to content

Commit 6f95429

Browse files
authored
feat(astro): Support clerk/ui (#7206)
1 parent 7bf9836 commit 6f95429

File tree

8 files changed

+54
-17
lines changed

8 files changed

+54
-17
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,8 @@ jobs:
294294
strategy:
295295
fail-fast: false
296296
matrix:
297-
test-name: [
297+
test-name:
298+
[
298299
"generic",
299300
"express",
300301
"ap-flows",
@@ -303,7 +304,7 @@ jobs:
303304
"sessions:staging",
304305
"handshake",
305306
"handshake:staging",
306-
# "astro",
307+
"astro",
307308
"tanstack-react-start",
308309
"vue",
309310
"nuxt",
@@ -403,7 +404,8 @@ jobs:
403404
uses: ./.github/actions/verdaccio
404405
with:
405406
publish-cmd: |
406-
if [ "$(pnpm config get registry)" = "https://registry.npmjs.org/" ]; then echo 'Error: Using default registry' && exit 1; else CLERK_USE_RQ=${{ matrix.clerk-use-rq }} pnpm turbo build $TURBO_ARGS --only && pnpm changeset publish --no-git-tag; fi
407+
if [ "$(pnpm config get registry)" = "https://registry.npmjs.org/" ]; then echo 'Error: Using default registry' && exit 1; else CLERK_USE_RQ=${{ matrix.clerk-use-rq }} pnpm turbo build $TURBO_ARGS --only && pnpm changeset publish --no-git-tag --tag integration; fi
408+
407409
408410
- name: Edit .npmrc [link-workspace-packages=false]
409411
run: sed -i -E 's/link-workspace-packages=(deep|true)/link-workspace-packages=false/' .npmrc

integration/presets/custom-flows.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { constants } from '../constants';
21
import { applicationConfig } from '../models/applicationConfig';
32
import { templates } from '../templates';
43
import { linkPackage } from './utils';
@@ -11,8 +10,9 @@ const reactVite = applicationConfig()
1110
.addScript('dev', 'pnpm dev')
1211
.addScript('build', 'pnpm build')
1312
.addScript('serve', 'pnpm preview')
14-
.addDependency('@clerk/react', constants.E2E_CLERK_JS_VERSION || linkPackage('react'))
15-
.addDependency('@clerk/themes', constants.E2E_CLERK_JS_VERSION || linkPackage('themes'));
13+
.addDependency('@clerk/react', linkPackage('react', 'integration'))
14+
.addDependency('@clerk/shared', linkPackage('shared', 'integration'))
15+
.addDependency('@clerk/themes', linkPackage('themes', 'integration'));
1616

1717
export const customFlows = {
1818
reactVite,

integration/presets/react.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { constants } from '../constants';
21
import { applicationConfig } from '../models/applicationConfig';
32
import { templates } from '../templates';
43
import { linkPackage } from './utils';
@@ -11,8 +10,9 @@ const cra = applicationConfig()
1110
.addScript('dev', 'pnpm start')
1211
.addScript('build', 'pnpm build')
1312
.addScript('serve', 'pnpm start')
14-
.addDependency('@clerk/react', constants.E2E_CLERK_JS_VERSION || linkPackage('react'))
15-
.addDependency('@clerk/themes', constants.E2E_CLERK_JS_VERSION || linkPackage('themes'));
13+
.addDependency('@clerk/react', linkPackage('react', 'integration'))
14+
.addDependency('@clerk/shared', linkPackage('shared', 'integration'))
15+
.addDependency('@clerk/themes', linkPackage('themes', 'integration'));
1616

1717
const vite = cra
1818
.clone()

integration/presets/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import path from 'node:path';
22

3-
export function linkPackage(pkg: string) {
3+
export function linkPackage(pkg: string, tag?: string) {
44
// eslint-disable-next-line turbo/no-undeclared-env-vars
55
if (process.env.CI === 'true') {
6-
return '*';
6+
return tag || '*';
77
}
88

99
return `link:${path.resolve(process.cwd(), `packages/${pkg}`)}`;

packages/astro/src/integration/create-integration.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ const buildEnvVarFromOption = (valueToBeStored: unknown, envName: keyof Internal
1111
};
1212

1313
type HotloadAstroClerkIntegrationParams = AstroClerkIntegrationParams & {
14-
clerkJSUrl?: string;
15-
clerkJSVariant?: 'headless' | '';
16-
clerkJSVersion?: string;
1714
enableEnvSchema?: boolean;
1815
};
1916

packages/astro/src/internal/create-clerk-instance.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
import { loadClerkJsScript, setClerkJsLoadingErrorPackageName } from '@clerk/shared/loadClerkJsScript';
1+
import {
2+
loadClerkJsScript,
3+
loadClerkUiScript,
4+
setClerkJsLoadingErrorPackageName,
5+
} from '@clerk/shared/loadClerkJsScript';
26
import type { ClerkOptions } from '@clerk/shared/types';
7+
import type { ClerkUiConstructor } from '@clerk/shared/ui';
38

49
import { $clerkStore } from '../stores/external';
510
import { $clerk, $csrState } from '../stores/internal';
@@ -31,8 +36,20 @@ const createClerkInstance = runOnce(createClerkInstanceInternal);
3136

3237
async function createClerkInstanceInternal(options?: AstroClerkCreateInstanceParams) {
3338
let clerkJSInstance = window.Clerk;
39+
let clerkUiCtor: Promise<ClerkUiConstructor> | undefined;
40+
3441
if (!clerkJSInstance) {
35-
await loadClerkJsScript(options);
42+
// Load both clerk-js and clerk-ui in parallel
43+
const clerkPromise = loadClerkJsScript(options);
44+
clerkUiCtor = loadClerkUiScript(options).then(() => {
45+
if (!window.__unstable_ClerkUiCtor) {
46+
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
47+
}
48+
// After the check, TypeScript knows it's defined
49+
return window.__unstable_ClerkUiCtor;
50+
});
51+
52+
await clerkPromise;
3653

3754
if (!window.Clerk) {
3855
throw new Error('Failed to download latest ClerkJS. Contact support@clerk.com.');
@@ -48,6 +65,8 @@ async function createClerkInstanceInternal(options?: AstroClerkCreateInstancePar
4865
routerPush: createNavigationHandler(window.history.pushState.bind(window.history)),
4966
routerReplace: createNavigationHandler(window.history.replaceState.bind(window.history)),
5067
...options,
68+
// Pass the clerk-ui constructor promise to clerk.load()
69+
clerkUiCtor,
5170
};
5271

5372
return clerkJSInstance

packages/astro/src/internal/merge-env-vars-with-params.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ const mergeEnvVarsWithParams = (params?: AstroClerkIntegrationParams & { publish
1414
domain: paramDomain,
1515
publishableKey: paramPublishableKey,
1616
telemetry: paramTelemetry,
17+
clerkJSUrl: paramClerkJSUrl,
18+
clerkUiUrl: paramClerkUiUrl,
19+
clerkJSVariant: paramClerkJSVariant,
20+
clerkJSVersion: paramClerkJSVersion,
1721
...rest
1822
} = params || {};
1923

@@ -24,6 +28,10 @@ const mergeEnvVarsWithParams = (params?: AstroClerkIntegrationParams & { publish
2428
proxyUrl: paramProxy || import.meta.env.PUBLIC_CLERK_PROXY_URL,
2529
domain: paramDomain || import.meta.env.PUBLIC_CLERK_DOMAIN,
2630
publishableKey: paramPublishableKey || import.meta.env.PUBLIC_CLERK_PUBLISHABLE_KEY || '',
31+
clerkUiUrl: paramClerkUiUrl || import.meta.env.PUBLIC_CLERK_UI_URL,
32+
clerkJSUrl: paramClerkJSUrl || import.meta.env.PUBLIC_CLERK_JS_URL,
33+
clerkJSVariant: paramClerkJSVariant || import.meta.env.PUBLIC_CLERK_JS_VARIANT,
34+
clerkJSVersion: paramClerkJSVersion || import.meta.env.PUBLIC_CLERK_JS_VERSION,
2735
telemetry: paramTelemetry || {
2836
disabled: isTruthy(import.meta.env.PUBLIC_CLERK_TELEMETRY_DISABLED),
2937
debug: isTruthy(import.meta.env.PUBLIC_CLERK_TELEMETRY_DEBUG),

packages/astro/src/types.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
ProtectProps,
77
Without,
88
} from '@clerk/shared/types';
9+
import type { ClerkUiConstructor } from '@clerk/shared/ui';
910

1011
type AstroClerkUpdateOptions = Pick<ClerkOptions, 'appearance' | 'localization'>;
1112

@@ -20,8 +21,17 @@ type AstroClerkIntegrationParams = Without<
2021
| 'routerPush'
2122
| 'polling'
2223
| 'touchSession'
24+
| 'clerkUiCtor'
2325
> &
24-
MultiDomainAndOrProxyPrimitives;
26+
MultiDomainAndOrProxyPrimitives & {
27+
clerkJSUrl?: string;
28+
clerkJSVariant?: 'headless' | '';
29+
clerkJSVersion?: string;
30+
/**
31+
* The URL that `@clerk/ui` should be hot-loaded from.
32+
*/
33+
clerkUiUrl?: string;
34+
};
2535

2636
type AstroClerkCreateInstanceParams = AstroClerkIntegrationParams & { publishableKey: string };
2737

@@ -42,6 +52,7 @@ declare global {
4252
__astro_clerk_component_props: Map<string, Map<string, Record<string, unknown>>>;
4353
__astro_clerk_function_props: Map<string, Map<string, Record<string, unknown>>>;
4454
Clerk: BrowserClerk;
55+
__unstable_ClerkUiCtor?: ClerkUiConstructor;
4556
}
4657
}
4758

0 commit comments

Comments
 (0)