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
20 changes: 20 additions & 0 deletions .changeset/chilly-suns-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@clerk/astro': minor
---

Add support for type-safe environment variables using the [`astro:env` API](https://docs.astro.build/en/reference/configuration-reference/#env).

The integration now provides a type-safe schema for all Clerk environment variables by default. You can use the environment variables like so:

```js
import { PUBLIC_CLERK_PUBLISHABLE_KEY } from "astro:env/client"
import { CLERK_SECRET_KEY } from "astro:env/server"
```

To override this behavior, you can disable the feature by setting `enableEnvSchema` to `false`:

```js
export default defineConfig({
integrations: [clerk({ enableEnvSchema: false })],
})
```
4 changes: 3 additions & 1 deletion packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@
"nanoid": "5.0.9",
"nanostores": "0.11.3"
},
"devDependencies": {},
"devDependencies": {
"astro": "^5.2.5"
},
"peerDependencies": {
"astro": "^4.15.0 || ^5.0.0"
},
Expand Down
32 changes: 31 additions & 1 deletion packages/astro/src/integration/create-integration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ClerkOptions } from '@clerk/types';
import type { AstroIntegration } from 'astro';
import { envField } from 'astro/config';

import { name as packageName, version as packageVersion } from '../../package.json';
import type { AstroClerkIntegrationParams } from '../types';
Expand All @@ -13,11 +14,12 @@ type HotloadAstroClerkIntegrationParams = AstroClerkIntegrationParams & {
clerkJSUrl?: string;
clerkJSVariant?: 'headless' | '';
clerkJSVersion?: string;
enableEnvSchema?: boolean;
};

function createIntegration<Params extends HotloadAstroClerkIntegrationParams>() {
return (params?: Params): AstroIntegration => {
const { proxyUrl, isSatellite, domain, signInUrl, signUpUrl } = params || {};
const { proxyUrl, isSatellite, domain, signInUrl, signUpUrl, enableEnvSchema = true } = params || {};

// These are not provided when the "bundled" integration is used
const clerkJSUrl = (params as any)?.clerkJSUrl as string | undefined;
Expand Down Expand Up @@ -79,6 +81,11 @@ function createIntegration<Params extends HotloadAstroClerkIntegrationParams>()
target: 'es2022',
},
},
env: {
schema: {
...(enableEnvSchema ? createClerkEnvSchema() : {}),
},
},
});

/**
Expand Down Expand Up @@ -158,4 +165,27 @@ function createIntegration<Params extends HotloadAstroClerkIntegrationParams>()
};
}

function createClerkEnvSchema() {
return {
PUBLIC_CLERK_PUBLISHABLE_KEY: envField.string({ context: 'client', access: 'public' }),
PUBLIC_CLERK_SIGN_IN_URL: envField.string({ context: 'client', access: 'public', optional: true }),
PUBLIC_CLERK_SIGN_UP_URL: envField.string({ context: 'client', access: 'public', optional: true }),
PUBLIC_CLERK_IS_SATELLITE: envField.boolean({ context: 'client', access: 'public', optional: true }),
PUBLIC_CLERK_PROXY_URL: envField.string({ context: 'client', access: 'public', optional: true, url: true }),
PUBLIC_CLERK_DOMAIN: envField.string({ context: 'client', access: 'public', optional: true, url: true }),
PUBLIC_CLERK_JS_URL: envField.string({ context: 'client', access: 'public', optional: true, url: true }),
PUBLIC_CLERK_JS_VARIANT: envField.enum({
context: 'client',
access: 'public',
optional: true,
values: ['headless'],
}),
PUBLIC_CLERK_JS_VERSION: envField.string({ context: 'client', access: 'public', optional: true }),
PUBLIC_CLERK_TELEMETRY_DISABLED: envField.boolean({ context: 'client', access: 'public', optional: true }),
PUBLIC_CLERK_TELEMETRY_DEBUG: envField.boolean({ context: 'client', access: 'public', optional: true }),
CLERK_SECRET_KEY: envField.string({ context: 'server', access: 'secret' }),
CLERK_JWT_KEY: envField.string({ context: 'server', access: 'secret', optional: true }),
};
}

export { createIntegration };
5 changes: 3 additions & 2 deletions packages/astro/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"forceConsistentCasingInFileNames": true,
"inlineSources": false,
"isolatedModules": true,
"moduleResolution": "node",
"moduleResolution": "Bundler",
Copy link
Member Author

@wobsoriano wobsoriano Feb 8, 2025

Choose a reason for hiding this comment

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

We need to update this to properly resolve imports from packages that use export maps (like astro/config)

"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveWatchOutput": true,
Expand All @@ -22,7 +22,8 @@
"outDir": "dist",
"resolveJsonModule": true,
"declarationDir": "dist/types",
"noUncheckedIndexedAccess": true
"noUncheckedIndexedAccess": true,
"rootDir": "src"
},
"exclude": [
"dist",
Expand Down
Loading