9 | This content is visible only to
10 | signed in users.
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Vite does not define `global` by default
3 | * One workaround is to use the `define` config prop
4 | * https://vitejs.dev/config/#define
5 | * We are solving this in the SDK level to reduce setup steps.
6 | */
7 | if (typeof window !== 'undefined' && !window.global)
8 | window.global = typeof globalThis === 'undefined' ? window : globalThis
9 |
10 | export {}
11 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/plugin.ts:
--------------------------------------------------------------------------------
1 | import type { Plugin } from 'vue'
2 | import type { InitialState } from '@clerk/types'
3 | import type { IsomorphicClerkOptions } from './types'
4 |
5 | import { provideClerkToVueApp } from './provideClerkToVueApp'
6 |
7 | export const clerkPlugin: Plugin = {
8 | install(app, options: IsomorphicClerkOptions & { initialState?: InitialState }) {
9 | provideClerkToVueApp(app, options)
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/utils/deprecate.ts:
--------------------------------------------------------------------------------
1 | export function getDeprecationMessage() {
2 | return `
3 | DEPRECATION NOTICE
4 | ==================
5 |
6 | The vue-clerk package has graduated to an official SDK!
7 |
8 | Please visit our migration guide:
9 | https://clerk.com/docs/references/vue/migrating-from-vue-community-sdk
10 |
11 | The community SDK will continue to work but will no longer
12 | receive updates or security patches.
13 | `
14 | }
15 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/utils/isConstructor.ts:
--------------------------------------------------------------------------------
1 | /*!
2 | * Original code by Clerk, Inc.
3 | * MIT Licensed, Copyright 2022 Clerk, Inc., see https://github.com/clerk/javascript/blob/main/packages/react/LICENSE for details
4 | *
5 | * Credits to the Clerk team:
6 | * https://github.com/clerk/javascript/blob/main/packages/react/src/utils/isConstructor.ts
7 | */
8 |
9 | export function isConstructor(f: any): f is T {
10 | return typeof f === 'function'
11 | }
12 |
--------------------------------------------------------------------------------
/apps/playground/pages/custom-pages.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
👋
6 |
7 |
Here is the user profile content
8 |
9 |
10 |
11 |
👋
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/packages/nuxt/scripts/watch.mjs:
--------------------------------------------------------------------------------
1 | import path from 'node:path'
2 | import nodemon from 'nodemon'
3 |
4 | // Unbuild doesn't have a built in watcher mode,
5 | // so we can use nodemon to watch the source files and rebuild the project when they change.
6 | nodemon({
7 | // eslint-disable-next-line node/prefer-global/process
8 | watch: [path.relative(process.cwd(), './src')],
9 | ext: '*',
10 | exec: 'pnpm run build',
11 | }).on('quit', () => {
12 | // eslint-disable-next-line node/prefer-global/process
13 | process.exit()
14 | })
15 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/composables/useClerkProvider.ts:
--------------------------------------------------------------------------------
1 | import { inject } from 'vue'
2 | import type { VueClerkInjectionKeyType } from '../keys'
3 | import { VueClerkInjectionKey } from '../keys'
4 |
5 | export function useClerkProvider() {
6 | const ctx = inject(VueClerkInjectionKey)
7 |
8 | if (!ctx) {
9 | throw new Error(
10 | 'This composable can only be used when the Vue Clerk plugin is installed. Learn more: https://vue-clerk.com/plugin',
11 | )
12 | }
13 |
14 | return ctx
15 | }
16 |
--------------------------------------------------------------------------------
/scripts/nuke.sh:
--------------------------------------------------------------------------------
1 | rm -rf node_modules pnpm-lock.yaml .turbo
2 |
3 | safe_remove() {
4 | [ -d "$1" ] && rm -rf "$1"
5 | }
6 |
7 | dirs_to_remove=(
8 | "node_modules"
9 | "dist"
10 | ".nuxt"
11 | ".vitepress/cache"
12 | ".vitepress/dist"
13 | ".output"
14 | ".turbo"
15 | )
16 |
17 | for base in packages apps; do
18 | for d in "$base"/*; do
19 | echo "Cleaning $d"
20 | for dir in "${dirs_to_remove[@]}"; do
21 | safe_remove "$d/$dir"
22 | done
23 | done
24 | done
25 |
--------------------------------------------------------------------------------
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/apps/playground/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "playground",
3 | "type": "module",
4 | "private": true,
5 | "scripts": {
6 | "build": "nuxt build",
7 | "dev": "nuxt dev",
8 | "generate": "nuxt generate",
9 | "preview": "nuxt preview"
10 | },
11 | "dependencies": {
12 | "@clerk/backend": "^1.21.6",
13 | "@clerk/localizations": "^3.1.2",
14 | "@clerk/themes": "^2.1.35",
15 | "vue-clerk": "workspace:*"
16 | },
17 | "devDependencies": {
18 | "@types/node": "^20.14.9",
19 | "nuxt": "^3.13.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "tasks": {
4 | "build": {
5 | "dependsOn": ["^build"],
6 | "inputs": ["$TURBO_DEFAULT$", ".env*"],
7 | "outputs": [".nuxt/**", ".output/**", "dist/**"]
8 | },
9 | "dev": {
10 | "cache": false,
11 | "persistent": true
12 | },
13 | "playground#build": {
14 | "dependsOn": ["vue-clerk-nuxt#build"],
15 | "inputs": ["$TURBO_DEFAULT$", ".env*"],
16 | "outputs": [".nuxt/**", ".output/**", "dist/**"]
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/docs/components/control/clerk-loading.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state.
8 |
9 | ## Usage
10 |
11 | ```vue
12 |
15 |
16 |
17 |
18 |
Clerk is loading...
19 |
20 |
21 |
22 |
23 |
This div is always visible
24 |
25 | ```
26 |
--------------------------------------------------------------------------------
/packages/vue-clerk/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2018",
4 | "lib": ["esnext", "DOM"],
5 | "module": "esnext",
6 | "moduleResolution": "node",
7 | "resolveJsonModule": true,
8 | "types": ["vitest/globals"],
9 | "strict": true,
10 | "strictNullChecks": true,
11 | "declaration": true,
12 | "declarationDir": "./dist",
13 | "esModuleInterop": true,
14 | "skipDefaultLibCheck": true,
15 | "skipLibCheck": true
16 | },
17 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "global.d.ts"]
18 | }
19 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/errors/messages.ts:
--------------------------------------------------------------------------------
1 | export const invalidStateError
2 | = 'Invalid state. Feel free to submit a bug or reach out to support here: https://clerk.com/support'
3 |
4 | export const unsupportedNonBrowserDomainOrProxyUrlFunction
5 | = 'Unsupported usage of isSatellite, domain or proxyUrl. The usage of isSatellite, domain or proxyUrl as function is not supported in non-browser environments.'
6 |
7 | export const useAuthHasRequiresRoleOrPermission
8 | = 'Missing parameters. `has` from `useAuth` requires a permission or role key to be passed. Example usage: `has({permission: "org:posts:edit"`'
9 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/utils/toComputedRefs.ts:
--------------------------------------------------------------------------------
1 | import { type ComputedRef, computed } from 'vue'
2 |
3 | export type ToComputedRefs = {
4 | [K in keyof T]: ComputedRef;
5 | }
6 |
7 | /**
8 | * Converts a computed ref to an object of computed refs.
9 | * This will allow the composables to be destructurable and still maintain reactivity.
10 | */
11 | export function toComputedRefs(
12 | objectRef: ComputedRef,
13 | ): ToComputedRefs {
14 | const result = {} as any
15 |
16 | for (const key in objectRef.value)
17 | result[key] = computed(() => objectRef.value[key])
18 |
19 | return result
20 | }
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-clerk-monorepo",
3 | "private": true,
4 | "packageManager": "pnpm@9.13.0",
5 | "scripts": {
6 | "build": "turbo run build",
7 | "build-packages": "turbo run build --filter=\"./packages/*\"",
8 | "dev": "turbo run dev ",
9 | "lint": "eslint .",
10 | "lint:fix": "eslint . --fix",
11 | "release": "pnpm build-packages && changeset publish",
12 | "nuke": "./scripts/nuke.sh"
13 | },
14 | "devDependencies": {
15 | "@antfu/eslint-config": "^2.21.2",
16 | "@changesets/cli": "^2.27.7",
17 | "eslint": "^9.6.0",
18 | "turbo": "^2.2.3",
19 | "typescript": "^5.5.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/WithClerk.vue:
--------------------------------------------------------------------------------
1 |
12 |
13 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/apps/docs/components/control/redirect-to-userprofile.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component will navigate to the user profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack.
8 |
9 | ## Usage
10 |
11 | ```vue
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Please Sign In
22 |
23 |
24 | ```
25 |
--------------------------------------------------------------------------------
/apps/docs/components/control/signed-out.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application.
8 |
9 | ## Usage
10 |
11 | ```vue
12 |
15 |
16 |
17 |
18 |
19 | This content is always visible.
20 |
21 |
22 |
23 | This content is visible only to signed out users.
24 |
25 |
26 |
27 |
28 | ```
29 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/WithUser.vue:
--------------------------------------------------------------------------------
1 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/apps/docs/components/control/redirect-to-createorganization.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component will navigate to the create organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack.
8 |
9 | ## Usage
10 |
11 | ```vue
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Please Sign In
22 |
23 |
24 | ```
25 |
--------------------------------------------------------------------------------
/apps/docs/components/control/signed-in.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a User with an active Session signed in your application.
8 |
9 | ## Usage
10 |
11 | ```vue
12 |
15 |
16 |
17 |
18 |
19 | This content is always visible.
20 |
21 |
22 |
23 | This content is visible only to
24 | signed in users.
25 |
23 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/apps/docs/components/control/redirect-to-organizationprofile.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component will navigate to the organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack.
8 |
9 | ## Usage
10 |
11 | ```vue
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Please Sign In
22 |
23 |
24 | ```
25 |
--------------------------------------------------------------------------------
/packages/nuxt/src/runtime/middleware/guest.ts:
--------------------------------------------------------------------------------
1 | import { useAuth } from 'vue-clerk'
2 | import { defineNuxtRouteMiddleware, navigateTo, useRuntimeConfig } from '#imports'
3 |
4 | export default defineNuxtRouteMiddleware((to) => {
5 | const { userId } = useAuth()
6 |
7 | // If user is not authenticated, no need to redirect
8 | if (!userId.value) {
9 | return
10 | }
11 |
12 | // Get config values
13 | const config = useRuntimeConfig().public.clerk
14 |
15 | // Chain of fallbacks for redirect URL
16 | const redirectUrl = to.meta.auth?.navigateAuthenticatedTo
17 | || to.meta.auth?.authenticatedRedirectUrl
18 | || config.signInForceRedirectUrl
19 | || config.signInFallbackRedirectUrl
20 |
21 | return navigateTo(redirectUrl)
22 | })
23 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/WithSession.vue:
--------------------------------------------------------------------------------
1 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/apps/docs/components/organization/create-organization.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 |
8 |
9 |
10 | The `` component is used to render an organization creation UI that allows users to create brand new organizations within your application.
11 |
12 | ## Props
13 |
14 | Click [here](https://clerk.com/docs/components/organization/create-organization#properties) to see the full list of props available.
15 |
16 | ## Usage
17 |
18 | ```vue
19 |
22 |
23 |
24 |
25 |
26 | ```
27 |
--------------------------------------------------------------------------------
/apps/docs/components/user/user-profile.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 |
8 |
9 |
10 | The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings.
11 |
12 | ## Props
13 |
14 | Click [here](https://clerk.com/docs/components/user/user-profile#properties) to see the full list of props available.
15 |
16 | ## Usage
17 |
18 | ```vue
19 |
22 |
23 |
24 |
25 |
26 | ```
27 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/composables/useSessionList.ts:
--------------------------------------------------------------------------------
1 | import type { UseSessionListReturn } from '@clerk/types'
2 | import { computed } from 'vue'
3 |
4 | import type { ToComputedRefs } from '../utils'
5 | import { toComputedRefs } from '../utils'
6 | import { useClerkProvider } from './useClerkProvider'
7 |
8 | export function useSessionList(): ToComputedRefs {
9 | const { clerk, clientCtx } = useClerkProvider()
10 |
11 | const result = computed(() => {
12 | if (!clientCtx.value)
13 | return { isLoaded: false, sessions: undefined, setActive: undefined }
14 |
15 | return {
16 | isLoaded: true,
17 | sessions: clientCtx.value.sessions,
18 | setActive: clerk.setActive,
19 | }
20 | })
21 |
22 | return toComputedRefs(result)
23 | }
24 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/composables/useUser.ts:
--------------------------------------------------------------------------------
1 | import type { UseUserReturn } from '@clerk/types'
2 | import { computed } from 'vue'
3 | import type { ToComputedRefs } from '../utils'
4 | import { toComputedRefs } from '../utils'
5 | import { useClerkProvider } from './useClerkProvider'
6 |
7 | export function useUser(): ToComputedRefs {
8 | const { userCtx } = useClerkProvider()
9 |
10 | const result = computed(() => {
11 | if (userCtx.value === undefined)
12 | return { isLoaded: false, isSignedIn: undefined, user: undefined }
13 |
14 | if (userCtx.value === null)
15 | return { isLoaded: true, isSignedIn: false, user: null }
16 |
17 | return { isLoaded: true, isSignedIn: true, user: userCtx.value }
18 | })
19 |
20 | return toComputedRefs(result)
21 | }
22 |
--------------------------------------------------------------------------------
/.github/workflows/dependabot.yml:
--------------------------------------------------------------------------------
1 | name: Add changeset to Dependabot updates
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened, synchronize, labeled]
6 |
7 | jobs:
8 | dependabot:
9 | name: Update Dependabot PR
10 | runs-on: ubuntu-latest
11 | if: contains(github.event.pull_request.labels.*.name, 'dependencies')
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0
18 | ref: ${{ github.event.pull_request.head.ref }}
19 | - name: Update PR
20 | uses: StafflinePeoplePlus/dependabot-changesets@v0.1.5
21 | with:
22 | owner: wobsoriano
23 | repo: vue-clerk
24 | pr-number: ${{ github.event.pull_request.number }}
25 | token: ${{ secrets.GITHUB_TOKEN }}
26 |
--------------------------------------------------------------------------------
/apps/docs/components/control/clerk-loaded.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists.
8 |
9 | ## Usage
10 |
11 | ```vue
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ```
22 |
23 | ```vue
24 |
31 |
32 |
33 |
The content
34 |
35 | ```
36 |
--------------------------------------------------------------------------------
/.github/workflows/preview.yml:
--------------------------------------------------------------------------------
1 | name: Preview
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 | name: Build
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Checkout Repo
11 | uses: actions/checkout@v4
12 | with:
13 | fetch-depth: 0
14 | - uses: pnpm/action-setup@v4
15 | with:
16 | version: 9.13.0
17 |
18 | - name: Setup Node.js
19 | uses: actions/setup-node@v4
20 | with:
21 | node-version: 20.x
22 | cache: pnpm
23 |
24 | - name: Install dependencies
25 | run: pnpm install --frozen-lockfile
26 |
27 | - name: Build
28 | run: pnpm build-packages
29 |
30 | - name: Create a snapshot version
31 | id: snapshot
32 | run: pnpm dlx pkg-pr-new publish './packages/vue-clerk' --compact
33 |
--------------------------------------------------------------------------------
/packages/nuxt/src/runtime/plugins/clerk.ts:
--------------------------------------------------------------------------------
1 | import { clerkPlugin } from 'vue-clerk'
2 | import type { InitialState } from '@clerk/types'
3 | import { defineNuxtPlugin, navigateTo, useRuntimeConfig, useState } from '#imports'
4 |
5 | export default defineNuxtPlugin({
6 | name: 'vue-clerk',
7 | setup(nuxtApp) {
8 | const initialState = useState('clerk-initial-state', () => undefined)
9 |
10 | if (import.meta.server) {
11 | initialState.value = nuxtApp.ssrContext?.event.context.__clerk_initial_state
12 | }
13 |
14 | nuxtApp.vueApp.use(clerkPlugin, {
15 | ...useRuntimeConfig().public.clerk,
16 | routerPush: (to: string) => navigateTo(to),
17 | routerReplace: (to: string) => navigateTo(to, { replace: true }),
18 | initialState: initialState.value,
19 | })
20 | },
21 | })
22 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/composables/useSession.ts:
--------------------------------------------------------------------------------
1 | import type { UseSessionReturn } from '@clerk/types'
2 | import { computed } from 'vue'
3 | import type { ToComputedRefs } from '../utils'
4 | import { toComputedRefs } from '../utils'
5 | import { useClerkProvider } from './useClerkProvider'
6 |
7 | export function useSession(): ToComputedRefs {
8 | const { sessionCtx } = useClerkProvider()
9 |
10 | const result = computed(() => {
11 | if (sessionCtx.value === undefined)
12 | return { isLoaded: false, isSignedIn: undefined, session: undefined }
13 |
14 | if (sessionCtx.value === null)
15 | return { isLoaded: true, isSignedIn: false, session: null }
16 |
17 | return { isLoaded: true, isSignedIn: true, session: sessionCtx.value }
18 | })
19 |
20 | return toComputedRefs(result)
21 | }
22 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/utils/useClerkLoaded.ts:
--------------------------------------------------------------------------------
1 | import { watch } from 'vue'
2 |
3 | import { useClerkProvider } from '../composables/useClerkProvider'
4 | import type { IsomorphicClerk } from '../isomorphicClerk'
5 |
6 | /**
7 | * Executes a callback when Clerk is loaded.
8 | *
9 | * @param callback - Function to execute once Clerk is loaded
10 | * @example
11 | * ```ts
12 | * useClerkLoaded((clerk) => {
13 | * clerk.redirectToSignUp(props);
14 | * });
15 | * ```
16 | */
17 | export function useClerkLoaded(callback: (clerk: IsomorphicClerk) => void) {
18 | const { isClerkLoaded, clerk } = useClerkProvider()
19 |
20 | const stop = watch(
21 | isClerkLoaded,
22 | (loaded) => {
23 | if (!loaded) {
24 | return
25 | }
26 |
27 | callback(clerk)
28 | stop()
29 | },
30 | { immediate: true },
31 | )
32 | }
33 |
--------------------------------------------------------------------------------
/apps/docs/components/control/redirect-to-signup.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack.
8 |
9 | ## Props
10 |
11 | Click [here](https://clerk.com/docs/components/control/redirect-to-signup#properties) to see the full list of props available.
12 |
13 | ## Usage
14 |
15 | ```vue
16 |
19 |
20 |
21 |
22 | Content that is displayed to signed in users.
23 |
24 |
25 |
26 |
27 |
28 | ```
29 |
--------------------------------------------------------------------------------
/packages/nuxt/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-clerk-nuxt",
3 | "type": "module",
4 | "version": "0.0.0",
5 | "private": true,
6 | "license": "MIT",
7 | "scripts": {
8 | "dev": "node ./scripts/watch.mjs",
9 | "postinstall": "nuxt-module-build prepare",
10 | "build": "nuxt-module-build build && pnpm run move",
11 | "move": "rm -rf ../vue-clerk/dist/nuxt && cp -R dist ../vue-clerk/dist/nuxt"
12 | },
13 | "dependencies": {
14 | "@clerk/backend": "^1.21.6",
15 | "@clerk/types": "^4.40.2",
16 | "@nuxt/kit": "^3.13.2",
17 | "@nuxt/schema": "^3.13.2",
18 | "h3": "^1.12.0",
19 | "vue-clerk": "workspace:*"
20 | },
21 | "devDependencies": {
22 | "@nuxt/devtools": "1.4.2",
23 | "@nuxt/module-builder": "0.8.4",
24 | "@types/node": "^22.5.1",
25 | "nodemon": "^3.1.4",
26 | "nuxt": "3.13.2"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/apps/docs/components/control/redirect-to-signin.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack.
8 |
9 | ## Props
10 |
11 | Click [here](https://clerk.com/docs/components/control/redirect-to-signin#properties) to see the full list of props available.
12 |
13 | ## Usage
14 |
15 | ```vue
16 |
19 |
20 |
21 |
22 | Content that is displayed to signed in
23 | users.
24 |
25 |
26 |
27 |
28 |
29 | ```
30 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/errors/errorThrower.ts:
--------------------------------------------------------------------------------
1 | /*!
2 | * Original code by Clerk, Inc.
3 | * MIT Licensed, Copyright 2022 Clerk, Inc., see https://github.com/clerk/javascript/blob/main/packages/react/LICENSE for details
4 | *
5 | * Credits to the Clerk team:
6 | * https://github.com/clerk/javascript/blob/main/packages/react/src/errors/errorThrower.ts
7 | */
8 |
9 | import type { ErrorThrowerOptions } from '@clerk/shared/error'
10 | import { buildErrorThrower } from '@clerk/shared/error'
11 |
12 | const errorThrower = buildErrorThrower({ packageName: PACKAGE_NAME })
13 |
14 | export { errorThrower }
15 |
16 | /**
17 | * Overrides options of the internal errorThrower (eg setting packageName prefix).
18 | *
19 | * @internal
20 | */
21 | export function setErrorThrowerOptions(options: ErrorThrowerOptions) {
22 | errorThrower.setMessages(options).setPackageName(options)
23 | }
24 |
--------------------------------------------------------------------------------
/packages/vue-clerk/tsup.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'tsup'
2 |
3 | import vuePlugin from 'unplugin-vue/esbuild'
4 | import autoPropsPlugin from '@vue.ts/tsx-auto-props/esbuild'
5 | import { name, version } from './package.json'
6 |
7 | export default defineConfig(() => {
8 | return {
9 | entry: {
10 | index: 'src/index.ts',
11 | internal: 'src/internal.ts',
12 | },
13 | format: ['cjs', 'esm'],
14 | splitting: true,
15 | clean: false,
16 | minify: false,
17 | dts: false,
18 | esbuildPlugins: [
19 | // Adds .vue files support
20 | vuePlugin(),
21 | // Adds runtime props type generation from TS types
22 | autoPropsPlugin({
23 | include: ['**/*.ts'],
24 | }),
25 | ],
26 | define: {
27 | PACKAGE_NAME: `"${name}"`,
28 | PACKAGE_VERSION: `"${version}"`,
29 | },
30 | }
31 | })
32 |
--------------------------------------------------------------------------------
/packages/nuxt/src/runtime/middleware/auth.ts:
--------------------------------------------------------------------------------
1 | import { useAuth } from 'vue-clerk'
2 | import type { CheckAuthorizationWithCustomPermissions } from '@clerk/types'
3 | import { defineNuxtRouteMiddleware, navigateTo } from '#imports'
4 |
5 | export default defineNuxtRouteMiddleware((to) => {
6 | const { userId, has } = useAuth()
7 | const { condition, permission, role, navigateUnauthenticatedTo, guestRedirectUrl } = to.meta?.auth || {}
8 | const redirectUrl = navigateUnauthenticatedTo || guestRedirectUrl
9 |
10 | if ((permission || role) && !has.value?.({ permission, role } as Parameters[0])) {
11 | return navigateTo(redirectUrl)
12 | }
13 |
14 | if (typeof condition === 'function' && !condition(has.value!)) {
15 | return navigateTo(redirectUrl)
16 | }
17 |
18 | if (!userId.value) {
19 | return navigateTo(redirectUrl)
20 | }
21 | })
22 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/composables/useSignIn.ts:
--------------------------------------------------------------------------------
1 | import type { UseSignInReturn } from '@clerk/types'
2 | import { computed } from 'vue'
3 | import { eventMethodCalled } from '@clerk/shared/telemetry'
4 | import type { ToComputedRefs } from '../utils'
5 | import { toComputedRefs } from '../utils'
6 | import { useClerkProvider } from './useClerkProvider'
7 |
8 | export function useSignIn(): ToComputedRefs {
9 | const { clerk, clientCtx } = useClerkProvider()
10 |
11 | clerk.telemetry?.record(eventMethodCalled('useSignIn'))
12 |
13 | const result = computed(() => {
14 | if (!clientCtx.value)
15 | return { isLoaded: false, signIn: undefined, setActive: undefined }
16 |
17 | return {
18 | isLoaded: true,
19 | signIn: clientCtx.value.signIn,
20 | setActive: clerk.setActive,
21 | }
22 | })
23 |
24 | return toComputedRefs(result)
25 | }
26 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/composables/useSignUp.ts:
--------------------------------------------------------------------------------
1 | import type { UseSignUpReturn } from '@clerk/types'
2 | import { computed } from 'vue'
3 | import { eventMethodCalled } from '@clerk/shared/telemetry'
4 | import type { ToComputedRefs } from '../utils'
5 | import { toComputedRefs } from '../utils'
6 | import { useClerkProvider } from './useClerkProvider'
7 |
8 | export function useSignUp(): ToComputedRefs {
9 | const { clerk, clientCtx } = useClerkProvider()
10 |
11 | clerk.telemetry?.record(eventMethodCalled('useSignUp'))
12 |
13 | const result = computed(() => {
14 | if (!clientCtx.value)
15 | return { isLoaded: false, signUp: undefined, setActive: undefined }
16 |
17 | return {
18 | isLoaded: true,
19 | signUp: clientCtx.value.signUp,
20 | setActive: clerk.setActive,
21 | }
22 | })
23 |
24 | return toComputedRefs(result)
25 | }
26 |
--------------------------------------------------------------------------------
/apps/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | # https://vitepress.dev/reference/default-theme-home-page
3 | layout: home
4 |
5 | hero:
6 | name: "Vue Clerk"
7 | text: "Clerk composables and components"
8 | tagline: Easiest way to add authentication and user management to your Vue application
9 | actions:
10 | - theme: brand
11 | text: What is Vue Clerk?
12 | link: /what-is-vue-clerk
13 | - theme: alt
14 | text: Quickstart
15 | link: /getting-started
16 | - theme: alt
17 | text: View on GitHub
18 | link: https://github.com/wobsoriano/vue-clerk
19 |
20 | features:
21 | - title: Pre-built Components
22 | details: Components for sign up, sign in, user management, and more.
23 | - title: Composables
24 | details: Composables for working with user, session and more.
25 | - title: Authentication & Users
26 | details: Passwords, SSO, OTP, MFA and other advanced security features.
27 | ---
28 |
--------------------------------------------------------------------------------
/apps/docs/composables/use-clerk.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # useClerk()
6 |
7 | The `useClerk()` composable provides access to the [`Clerk`](https://clerk.com/docs/references/javascript/clerk/clerk) object, giving you the ability to build alternatives to any Clerk Component.
8 |
9 | ::: warning
10 | This is intended to be used for advanced use cases, like building a completely custom OAuth flow or as an escape hatch for getting access to the `Clerk` object.
11 | :::
12 |
13 | ## Returns
14 |
15 | The `useClerk()` composable returns the `Clerk` object, which includes all the methods and properties listed in the [`Clerk` reference](https://clerk.com/docs/references/javascript/clerk/clerk).
16 |
17 | ## Usage
18 |
19 | ```vue
20 |
25 |
26 |
27 |
30 |
31 | ```
32 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/SignInWithMetamaskButton.vue:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
25 |
30 |
31 |
--------------------------------------------------------------------------------
/packages/nuxt/src/runtime/server/clerkClient.ts:
--------------------------------------------------------------------------------
1 | import { createClerkClient } from '@clerk/backend'
2 | import type { H3Event } from 'h3'
3 | import { isTruthy } from './utils'
4 | import { useRuntimeConfig } from '#imports'
5 |
6 | export function clerkClient(event: H3Event) {
7 | const runtimeConfig = useRuntimeConfig(event)
8 | return createClerkClient({
9 | publishableKey: runtimeConfig.public.clerk.publishableKey,
10 | apiUrl: runtimeConfig.public.clerk.apiUrl,
11 | apiVersion: runtimeConfig.public.clerk.apiVersion,
12 | secretKey: runtimeConfig.clerk.secretKey,
13 | jwtKey: runtimeConfig.clerk.jwtKey,
14 | domain: runtimeConfig.public.clerk.domain,
15 | isSatellite: isTruthy(runtimeConfig.public.clerk.isSatellite),
16 | telemetry: {
17 | disabled: isTruthy(runtimeConfig.public.clerk.telemetry?.disabled),
18 | debug: isTruthy(runtimeConfig.public.clerk.telemetry?.debug),
19 | },
20 | })
21 | }
22 |
23 | export function getAuth(event: H3Event) {
24 | return event.context.auth
25 | }
26 |
--------------------------------------------------------------------------------
/apps/playground/README.md:
--------------------------------------------------------------------------------
1 | # Nuxt 3 Minimal Starter
2 |
3 | Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
4 |
5 | ## Setup
6 |
7 | Make sure to install the dependencies:
8 |
9 | ```bash
10 | # npm
11 | npm install
12 |
13 | # pnpm
14 | pnpm install
15 |
16 | # yarn
17 | yarn install
18 | ```
19 |
20 | ## Development Server
21 |
22 | Start the development server on `http://localhost:3000`:
23 |
24 | ```bash
25 | # npm
26 | npm run dev
27 |
28 | # pnpm
29 | pnpm run dev
30 |
31 | # yarn
32 | yarn dev
33 | ```
34 |
35 | ## Production
36 |
37 | Build the application for production:
38 |
39 | ```bash
40 | # npm
41 | npm run build
42 |
43 | # pnpm
44 | pnpm run build
45 |
46 | # yarn
47 | yarn build
48 | ```
49 |
50 | Locally preview production build:
51 |
52 | ```bash
53 | # npm
54 | npm run preview
55 |
56 | # pnpm
57 | pnpm run preview
58 |
59 | # yarn
60 | yarn preview
61 | ```
62 |
63 | Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
64 |
--------------------------------------------------------------------------------
/apps/docs/composables/use-session-list.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # useSessionList()
6 |
7 | The `useSessionList()` composable returns an array of [`Session`](https://clerk.com/docs/references/javascript/session) objects that have been registered on the client device.
8 |
9 | ## Returns
10 |
11 | Click [here](https://clerk.com/docs/references/react/use-session-list#use-session-list-returns) to see the full list of properties returned.
12 |
13 | ## Usage
14 |
15 | The following example demonstrates how to use the `useSessionList()` composable to retrieve a list of sessions that have been registered on the client device. The `isLoaded` property is used to handle the loading state, and the `sessions` property is used to display the number of times the user has visited the page.
16 |
17 | ```vue
18 |
23 |
24 |
25 |
26 |
27 | Welcome back. You have been here
28 | {{ sessions.length }} times before.
29 |
30 |
31 |
32 | ```
33 |
--------------------------------------------------------------------------------
/packages/nuxt/src/runtime/server/utils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Taken from https://github.com/clerk/javascript/blob/7a298bed566b71043ac4b8bf3cf132ef3006cf36/packages/shared/src/underscore.ts#L90
3 | *
4 | * Returns true for `true`, true, positive numbers.
5 | * Returns false for `false`, false, 0, negative integers and anything else.
6 | */
7 | export function isTruthy(value: unknown): boolean {
8 | // Return if Boolean
9 | if (typeof value === `boolean`) {
10 | return value
11 | }
12 |
13 | // Return false if null or undefined
14 | if (value === undefined || value === null) {
15 | return false
16 | }
17 |
18 | // If the String is true or false
19 | if (typeof value === `string`) {
20 | if (value.toLowerCase() === `true`) {
21 | return true
22 | }
23 |
24 | if (value.toLowerCase() === `false`) {
25 | return false
26 | }
27 | }
28 |
29 | // Now check if it's a number
30 | const number = Number.parseInt(value as string, 10)
31 | if (Number.isNaN(number)) {
32 | return false
33 | }
34 |
35 | if (number > 0) {
36 | return true
37 | }
38 |
39 | // Default to false
40 | return false
41 | }
42 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 |
11 | jobs:
12 | test:
13 | runs-on: ${{ matrix.os }}
14 | strategy:
15 | matrix:
16 | node: [20.x]
17 | os: [ubuntu-latest, windows-latest, macos-latest]
18 | fail-fast: false
19 |
20 | steps:
21 | - name: Checkout Repo
22 | uses: actions/checkout@v4
23 | with:
24 | fetch-depth: 0
25 | - uses: pnpm/action-setup@v4
26 | with:
27 | version: 9.13.0
28 |
29 | - name: Set up Node.js ${{ matrix.node }}
30 | uses: actions/setup-node@v4
31 | with:
32 | node-version: ${{ matrix.node }}
33 | cache: pnpm
34 |
35 | - name: Install dependencies
36 | run: pnpm install --frozen-lockfile
37 |
38 | - name: Lint
39 | run: pnpm lint
40 |
41 | - name: Typecheck
42 | run: pnpm --filter vue-clerk typecheck
43 |
44 | - name: Build
45 | run: pnpm build-packages
46 |
47 | - name: Test
48 | run: pnpm --filter vue-clerk test
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Robert Soriano
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/apps/docs/composables/use-session.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # useSession()
6 |
7 | The `useSession()` composable provides access to the current user's [`Session`](https://clerk.com/docs/references/javascript/session) object, as well as helpers for setting the active session.
8 |
9 | ## Returns
10 |
11 | Click [here](https://clerk.com/docs/references/react/use-session#use-session-returns) to see the full list of properties returned.
12 |
13 | ## Usage
14 |
15 | The following example demonstrates how to use the `useSession()` composable to access the `SignIn` object, which has the `lastActiveAt` property on it. The `lastActiveAt` property is used to display the last active time of the current session to the user.
16 |
17 | ```vue
18 |
23 |
24 |
25 |
26 | Loading...
27 |
28 |
29 | Not signed in
30 |
31 |
32 | This session has been active since {{ session.lastActiveAt.toLocaleString() }}.
33 |
34 |
35 | ```
36 |
--------------------------------------------------------------------------------
/packages/vue-clerk/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Robert Soriano
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/apps/playground/pages/index.vue:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
Hello Clerk!
16 |
17 |
18 | Loading auth..
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Hello {{ user?.fullName }}!
26 |
27 |
28 | Loading...
29 |
30 |
31 |
32 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/apps/docs/components/unstyled/sign-in-button.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component is a button that links to the sign-in page or displays the sign-in modal.
8 |
9 | ## Props
10 |
11 | Click [here](https://clerk.com/docs/components/unstyled/sign-in-button#sign-in-button-properties) to see the full list of props available.
12 |
13 | ## Slots
14 |
15 | |Name|Description|
16 | |:----|:----|
17 | |`default?`|children you want to wrap the `` in.|
18 |
19 | ## Usage
20 |
21 | ### Basic Usage
22 |
23 | ```vue
24 |
27 |
28 |
29 |
30 |
31 | ```
32 |
33 | ### Custom Usage
34 |
35 | In some cases you will want to use your own button, or button text. You can do that by passing your own button as a child and passing the `handler` to the `click` event.
36 |
37 | ```vue
38 |
41 |
42 |
43 |
44 |
Sign in
45 |
46 |
49 |
50 |
51 |
52 | ```
53 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/__tests__/SignOutButton.test.ts:
--------------------------------------------------------------------------------
1 | import { vi } from 'vitest'
2 | import { render, screen } from '@testing-library/vue'
3 | import { userEvent } from '@testing-library/user-event'
4 | import { defineComponent, h } from 'vue'
5 | import SignOutButton from '../SignOutButton.vue'
6 |
7 | const mockSignOut = vi.fn()
8 | const originalError = console.error
9 |
10 | vi.mock('../../composables/useClerk', async () => {
11 | return {
12 | useClerk: () => ({
13 | signOut: mockSignOut,
14 | }),
15 | }
16 | })
17 |
18 | describe('', () => {
19 | beforeAll(() => {
20 | console.error = vi.fn()
21 | })
22 |
23 | beforeEach(() => {
24 | mockSignOut.mockReset()
25 | })
26 |
27 | afterAll(() => {
28 | console.error = originalError
29 | })
30 |
31 | it('calls clerk.signOutOne when clicked', async () => {
32 | render(SignOutButton)
33 | const btn = screen.getByText('Sign out')
34 | await userEvent.click(btn)
35 |
36 | expect(mockSignOut).toHaveBeenCalled()
37 | })
38 |
39 | it('uses text passed as children', async () => {
40 | const Button = defineComponent(() => {
41 | return () => h(SignOutButton, () => 'text')
42 | })
43 | render(Button)
44 | screen.getByText('text')
45 | })
46 | })
47 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | concurrency: ${{ github.workflow }}-${{ github.ref }}
9 |
10 | jobs:
11 | release:
12 | permissions:
13 | contents: write # to create release (changesets/action)
14 | pull-requests: write # to create pull request (changesets/action)
15 | name: Release
16 | runs-on: ubuntu-latest
17 | steps:
18 | - name: Checkout Repo
19 | uses: actions/checkout@v4
20 | with:
21 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
22 | fetch-depth: 0
23 | - uses: pnpm/action-setup@v4
24 | with:
25 | version: 9.13.0
26 |
27 | - name: Setup Node.js
28 | uses: actions/setup-node@v4
29 | with:
30 | node-version: 20.x
31 | cache: pnpm
32 |
33 | - name: Install dependencies
34 | run: pnpm install --frozen-lockfile
35 |
36 | - name: Create Release Pull Request or Publish to npm
37 | id: changesets
38 | uses: changesets/action@v1
39 | with:
40 | publish: pnpm release
41 | env:
42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
44 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/keys.ts:
--------------------------------------------------------------------------------
1 | import type { ComputedRef, Ref } from 'vue'
2 | import type { ActJWTClaim, ActiveSessionResource, ClientResource, OrganizationCustomPermissionKey, OrganizationCustomRoleKey, OrganizationResource, UserResource } from '@clerk/types'
3 | import type { IsomorphicClerk } from './isomorphicClerk'
4 |
5 | export interface VueClerkInjectionKeyType {
6 | clerk: IsomorphicClerk
7 | isClerkLoaded: Ref
8 | authCtx: ComputedRef<{
9 | userId: string | null | undefined
10 | sessionId: string | null | undefined
11 | actor: ActJWTClaim | null | undefined
12 | orgId: string | null | undefined
13 | orgRole: OrganizationCustomRoleKey | null | undefined
14 | orgSlug: string | null | undefined
15 | orgPermissions: OrganizationCustomPermissionKey[] | null | undefined
16 | }>
17 | clientCtx: ComputedRef
18 | sessionCtx: ComputedRef
19 | userCtx: ComputedRef
20 | organizationCtx: ComputedRef
21 | }
22 |
23 | // Using Symbols causes issues in Nuxt. Investigate further.
24 | // export const VueClerkInjectionKey = Symbol('VueClerk') as InjectionKey
25 | export const VueClerkInjectionKey = '$$_clerk'
26 |
--------------------------------------------------------------------------------
/apps/docs/composables/use-auth.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # useAuth()
6 |
7 | The `useAuth()` composable is a convenient way to access the current auth state. This composable provides the minimal information needed for data-loading and helper methods to manage the current active session.
8 |
9 | ## Returns
10 |
11 | Click [here](https://clerk.com/docs/references/react/use-auth#use-auth-returns) to see the full list of properties returned.
12 |
13 | ## Usage
14 |
15 | The following example demonstrates how to use the `useAuth()` composable to access the current auth state, like whether the user is signed in or not. It also demonstrates a basic example of how you could use the `getToken()` method to retrieve a session token for fetching data from an external resource.
16 |
17 | ```vue
18 |
29 |
30 |
31 |
32 | Loading...
33 |
34 |
35 | Sign in to view this page
36 |
37 |
38 | ...
39 |
40 |
41 | ```
42 |
--------------------------------------------------------------------------------
/apps/docs/components/organization/organization-switcher.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 |
8 |
9 |
10 | The `` component allows a user to switch between their account types - their personal account and their joined organizations. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple organizations.
11 |
12 | Out of the box, this component will show notifications to the user if they have organization [invitations](https://clerk.com/docs/organizations/overview#organization-invitations) or [suggestions](https://clerk.com/docs/organizations/overview#suggestions). Admins will be able to see notifications for [requests](https://clerk.com/docs/organizations/overview#membership-requests) to join an organization.
13 |
14 | ## Props
15 |
16 | Click [here](https://clerk.com/docs/components/organization/organization-switcher#properties) to see the full list of props available.
17 |
18 | ## Usage
19 |
20 | ```vue
21 |
24 |
25 |
26 |
27 |
28 | ```
29 |
--------------------------------------------------------------------------------
/apps/docs/components/organization/organization-list.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 |
8 |
9 |
10 | The `` component is used to display organization related memberships, invitations, and suggestions for the user.
11 |
12 | ## Props
13 |
14 | Click [here](https://clerk.com/docs/components/organization/organization-list#properties) to see the full list of props available.
15 |
16 | ## Usage
17 |
18 | ```vue
19 |
22 |
23 |
24 |
29 |
30 | ```
31 |
32 | ### Force organizations
33 |
34 | If you would like to prohibit people from using their personal accounts and force them to be part of an organization, the `hidePersonal` property forces your user to join or create an organization in order to continue.
35 |
36 | ```vue
37 |
38 |
39 |
40 | ```
41 |
--------------------------------------------------------------------------------
/apps/docs/components/unstyled/sign-up-button.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | The `` component is a button that links to the sign-up page or displays the sign-up modal.
8 |
9 | ## Props
10 |
11 | Click [here](https://clerk.com/docs/components/unstyled/sign-up-button#sign-up-button-properties) to see the full list of props available.
12 |
13 | ## Slots
14 |
15 | |Name|Description|
16 | |:----|:----|
17 | |`default?`|children you want to wrap the `` in.|
18 |
19 | ## Usage
20 |
21 | ### Basic Usage
22 |
23 | ```vue
24 |
27 |
28 |
29 |
30 |
Sign up
31 |
32 |
33 |
34 | ```
35 |
36 | ### Custom Usage
37 |
38 | In some cases you will want to use your own button, or button text. You can do that by passing your own button as a child and passing the `handler` to the `click` event.
39 |
40 | ```vue
41 |
44 |
45 |
46 |
47 |
Sign up
48 |
49 |
54 |
55 |
56 |
57 | ```
58 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/__tests__/SignIn.test.ts:
--------------------------------------------------------------------------------
1 | import { expectTypeOf } from 'expect-type'
2 | import type { ComponentProps } from 'vue-component-type-helpers'
3 |
4 | import type { SignIn } from '../uiComponents'
5 |
6 | export type SignInComponentProps = ComponentProps
7 |
8 | describe('', () => {
9 | describe('type tests', () => {
10 | it('has path filled', () => {
11 | expectTypeOf({ path: '/sign-in' }).toMatchTypeOf()
12 | })
13 |
14 | it('has path filled and routing has path as a value', () => {
15 | expectTypeOf({
16 | path: '/sign-in',
17 | routing: 'path' as const,
18 | }).toMatchTypeOf()
19 | })
20 |
21 | it('when path is filled, routing must only have path as value', () => {
22 | expectTypeOf({
23 | path: '/sign-in',
24 | routing: 'virtual' as const,
25 | }).not.toMatchTypeOf()
26 |
27 | expectTypeOf({
28 | path: '/sign-in',
29 | routing: 'hash' as const,
30 | }).not.toMatchTypeOf()
31 | })
32 |
33 | it('when routing is hash or virtual path must be present', () => {
34 | expectTypeOf({
35 | routing: 'hash' as const,
36 | }).toMatchTypeOf()
37 | })
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/__tests__/SignUp.test.ts:
--------------------------------------------------------------------------------
1 | import { expectTypeOf } from 'expect-type'
2 | import type { ComponentProps } from 'vue-component-type-helpers'
3 |
4 | import type { SignUp } from '../uiComponents'
5 |
6 | export type SignUpComponentProps = ComponentProps
7 |
8 | describe('', () => {
9 | describe('type tests', () => {
10 | it('has path filled', () => {
11 | expectTypeOf({ path: '/sign-up' }).toMatchTypeOf()
12 | })
13 |
14 | it('has path filled and routing has path as a value', () => {
15 | expectTypeOf({
16 | path: '/sign-up',
17 | routing: 'path' as const,
18 | }).toMatchTypeOf()
19 | })
20 |
21 | it('when path is filled, routing must only have path as value', () => {
22 | expectTypeOf({
23 | path: '/sign-up',
24 | routing: 'virtual' as const,
25 | }).not.toMatchTypeOf()
26 |
27 | expectTypeOf({
28 | path: '/sign-up',
29 | routing: 'hash' as const,
30 | }).not.toMatchTypeOf()
31 | })
32 |
33 | it('when routing is hash or virtual path must be present', () => {
34 | expectTypeOf({
35 | routing: 'hash' as const,
36 | }).toMatchTypeOf()
37 | })
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/packages/vue-clerk/README.md:
--------------------------------------------------------------------------------
1 | # vue-clerk
2 |
3 | Vue Clerk is the easiest way to add authentication and user management to your Vue application. Add sign up, sign in, and profile management to your application in minutes.
4 |
5 | > [!IMPORTANT]
6 | > This project has graduated to an [official SDK](https://clerk.com/changelog/2025-01-07-vue-and-nuxt-sdk). Please proceed [here](https://clerk.com/docs/references/vue/migrating-from-vue-community-sdk) for migration instructions.
7 |
8 | ## Installation
9 |
10 | ```bash
11 | npm install vue-clerk
12 | ```
13 |
14 | ## Usage
15 |
16 | Vue Clerk requires your application to have the [`clerkPlugin`](https://vue-clerk.com/plugin) installed.
17 |
18 | If using Vite, set `VITE_CLERK_PUBLISHABLE_KEY` to your Publishable key in your `.env.local` file to make the environment variable accessible on `process.env` and pass it as the `publishableKey` prop.
19 |
20 | ```vue
21 |
24 |
25 |
26 |
Hello Clerk!
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | ```
35 |
36 | For further details and examples, please refer to the [Documentation](https://vue-clerk.vercel.app).
37 |
38 | ## License
39 |
40 | MIT
41 |
--------------------------------------------------------------------------------
/apps/docs/components/authentication/google-one-tap.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 | ::: info
8 | To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](https://clerk.com/docs/authentication/social-connections/google#configuring-google-social-connection) and make sure to use custom credentials.
9 | :::
10 |
11 | The `` component renders the [Google One Tap UI](https://developers.google.com/identity/gsi/web/guides/features) so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts.
12 |
13 | By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with [force redirect URL props](https://clerk.com/docs/components/authentication/google-one-tap#google-one-tap-props) or [force redirect URL environment variables](https://clerk.com/docs/deployments/clerk-environment-variables#sign-in-and-sign-up-redirects).
14 |
15 | ## Props
16 |
17 | Click [here](https://clerk.com/docs/components/authentication/google-one-tap#google-one-tap-props) to see the full list of props available.
18 |
19 | ## Usage
20 |
21 | ```vue
22 |
25 |
26 |
27 |
28 |
29 | ```
30 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/SignInButton.vue:
--------------------------------------------------------------------------------
1 |
34 |
35 |
36 |
40 |
45 |
46 |
--------------------------------------------------------------------------------
/apps/docs/what-is-vue-clerk.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # What is Vue Clerk?
6 |
7 | Vue Clerk is a wrapper around ClerkJS. It's a way to integrate Clerk into your Vue application.
8 |
9 | Vue Clerk provides Vue implementations of [Clerk Components](https://clerk.com/components/sign-in); highly customizable, pre-built components that you can use to build beautiful user management applications. You can find display components for building [sign in](https://clerk.com/components/sign-in), [sign up](https://clerk.com/components/sign-up), [account switching](https://clerk.com/components/user-button) and [user profile management](https://clerk.com/components/user-profile) pages as well as flow [control components](https://clerk.com/docs/component-reference/clerk-loaded) that act as helpers for implementing a seamless authentication experience.
10 |
11 | Vue Clerk comes loaded with custom [composables](/composables/use-clerk.html). These composables give you access to the [Clerk object](https://clerk.com/docs/reference/clerkjs/clerk), and a set of useful helper methods for signing in and signing up.
12 |
13 | ::: info
14 | To reduce the time of going back and forth between the official [Clerk docs](https://clerk.com/docs) and the Vue Clerk docs, we have copied most of the content you will see here (including images) from the Clerk docs and added some Vue-specific information.
15 | :::
16 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/SignOutButton.vue:
--------------------------------------------------------------------------------
1 |
35 |
36 |
37 |
41 |
46 |
47 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/__tests__/UserProfile.test.ts:
--------------------------------------------------------------------------------
1 | import { expectTypeOf } from 'expect-type'
2 | import type { ComponentProps } from 'vue-component-type-helpers'
3 |
4 | import type { UserProfile } from '../uiComponents'
5 |
6 | export type UserProfileComponentProps = ComponentProps
7 |
8 | describe('', () => {
9 | describe('type tests', () => {
10 | it('has path filled', () => {
11 | expectTypeOf({ path: '/profile' }).toMatchTypeOf()
12 | })
13 |
14 | it('has path filled and routing has path as a value', () => {
15 | expectTypeOf({
16 | path: '/profile',
17 | routing: 'path' as const,
18 | }).toMatchTypeOf()
19 | })
20 |
21 | it('when path is filled, routing must only have path as value', () => {
22 | expectTypeOf({
23 | path: '/profile',
24 | routing: 'virtual' as const,
25 | }).not.toMatchTypeOf()
26 |
27 | expectTypeOf({
28 | path: '/profile',
29 | routing: 'hash' as const,
30 | }).not.toMatchTypeOf()
31 | })
32 |
33 | it('when routing is hash or virtual path must be present', () => {
34 | expectTypeOf({
35 | routing: 'hash' as const,
36 | }).toMatchTypeOf()
37 | })
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/SignUpButton.vue:
--------------------------------------------------------------------------------
1 |
37 |
38 |
39 |
43 |
48 |
49 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/__tests__/OrganizationProfile.test.ts:
--------------------------------------------------------------------------------
1 | import { expectTypeOf } from 'expect-type'
2 | import type { ComponentProps } from 'vue-component-type-helpers'
3 |
4 | import type { OrganizationProfile } from '../uiComponents'
5 |
6 | export type OrganizationProfileComponentProps = ComponentProps
7 |
8 | describe('', () => {
9 | describe('type tests', () => {
10 | it('has path filled', () => {
11 | expectTypeOf({ path: '/org' }).toMatchTypeOf()
12 | })
13 |
14 | it('has path filled and routing has path as a value', () => {
15 | expectTypeOf({
16 | path: '/org',
17 | routing: 'path' as const,
18 | }).toMatchTypeOf()
19 | })
20 |
21 | it('when path is filled, routing must only have path as value', () => {
22 | expectTypeOf({
23 | path: '/org',
24 | routing: 'virtual' as const,
25 | }).not.toMatchTypeOf()
26 |
27 | expectTypeOf({
28 | path: '/org',
29 | routing: 'hash' as const,
30 | }).not.toMatchTypeOf()
31 | })
32 |
33 | it('when routing is hash or virtual path must be present', () => {
34 | expectTypeOf({
35 | routing: 'hash' as const,
36 | }).toMatchTypeOf()
37 | })
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/packages/vue-clerk/src/components/__tests__/SignInWithMetamaskButton.test.ts:
--------------------------------------------------------------------------------
1 | import { vi } from 'vitest'
2 | import { render, screen } from '@testing-library/vue'
3 | import { userEvent } from '@testing-library/user-event'
4 | import { defineComponent, h } from 'vue'
5 | import SignInWithMetamaskButton from '../SignInWithMetamaskButton.vue'
6 |
7 | const mockAuthenticatewithMetamask = vi.fn()
8 | const originalError = console.error
9 |
10 | vi.mock('../../composables/useClerk', async () => {
11 | return {
12 | useClerk: () => ({
13 | authenticateWithMetamask: mockAuthenticatewithMetamask,
14 | }),
15 | }
16 | })
17 |
18 | describe('', () => {
19 | beforeAll(() => {
20 | console.error = vi.fn()
21 | })
22 |
23 | beforeEach(() => {
24 | mockAuthenticatewithMetamask.mockReset()
25 | })
26 |
27 | afterAll(() => {
28 | console.error = originalError
29 | })
30 |
31 | it('calls clerk.authenticateWithMetamask when clicked', async () => {
32 | render(SignInWithMetamaskButton)
33 | const btn = screen.getByText('Sign in with Metamask')
34 | await userEvent.click(btn)
35 |
36 | expect(mockAuthenticatewithMetamask).toHaveBeenCalled()
37 | })
38 |
39 | it('uses text passed as children', async () => {
40 | const Button = defineComponent(() => {
41 | return () => h(SignInWithMetamaskButton, () => 'text')
42 | })
43 | render(Button)
44 | screen.getByText('text')
45 | })
46 | })
47 |
--------------------------------------------------------------------------------
/apps/playground/pages/user-button.vue:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
47 |
48 |
--------------------------------------------------------------------------------
/apps/docs/composables/use-sign-up.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # useSignUp()
6 |
7 | The `useSignUp()` composable gives you access to the [`SignUp`](https://clerk.com/docs/references/javascript/sign-up/sign-up) object, which allows you to check the current state of a sign-up. This is also useful for creating a custom sign-up flow.
8 |
9 | ## Returns
10 |
11 | Click [here](https://clerk.com/docs/references/react/use-sign-up#use-sign-up-returns) to see the full list of properties returned.
12 |
13 | ## Usage
14 |
15 | ### Check the current state of a up
16 |
17 | Use the `useSignUp()` composable to check the current state of a sign-up.
18 |
19 | ```vue
20 |
25 |
26 |
27 |
28 | The current sign-up attempt status is {{ signUp.status }}.
29 |
30 |
31 | Loading...
32 |
33 |
34 | ```
35 |
36 | ### Create a custom sign-up flow
37 |
38 | The `useSignUp()` composable can also be used to build fully custom sign-up flows, if Clerk's pre-built components don't meet your specific needs or if you require more control over the authentication flow. Different sign-up flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignUp()` composable to create custom flows, check out the [custom flow guides](https://clerk.com/docs/custom-flows/overview).
39 |
--------------------------------------------------------------------------------
/apps/docs/composables/use-sign-in.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # useSignIn()
6 |
7 | The `useSignIn()` composable provides access to the [`SignIn`](https://clerk.com/docs/references/javascript/sign-in/sign-in) object, which allows you to check the current state of a sign-in. This is also useful for creating a custom sign-in flow.
8 |
9 | ## Returns
10 |
11 | Click [here](https://clerk.com/docs/references/react/use-sign-in#use-sign-in-returns) to see the full list of properties returned.
12 |
13 | ## Usage
14 |
15 | ### Check the current state of a sign-in
16 |
17 | Use the `useSignIn()` composable to check the current state of a sign-in.
18 |
19 | ```vue
20 |
25 |
26 |
27 |
28 | The current sign in attempt status is {{ signIn.status }}.
29 |
30 |
31 | Loading...
32 |
33 |
34 | ```
35 |
36 | ### Create a custom sign-in flow
37 |
38 | The `useSignIn()` composable can also be used to build fully custom sign-in flows, if Clerk's pre-built components don't meet your specific needs or if you require more control over the authentication flow. Different sign-in flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignIn()` composable to create custom flows, check out the [custom flow guides](https://clerk.com/docs/custom-flows/overview).
39 |
--------------------------------------------------------------------------------
/apps/docs/components/organization/organization-profile.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 |
8 |
9 |
10 | The `` component is used to render a beautiful, full-featured organization management UI that allows users to manage their organization profile and security settings.
11 |
12 | Out of the box, this component's General tab displays the organization's information and the Leave organization button. Admins will be able to see the Update profile button, Verified domains section, and Delete organization button.
13 |
14 | The Members tab shows the organization's members along with their join dates and roles. Admins will have the ability to invite a member, change a member's role, or remove them from the organization. Admins will have tabs within the Members tab to view the organization's [invitations](https://clerk.com/docs/organizations/overview#organization-invitations) and [requests](https://clerk.com/docs/organizations/overview#membership-requests).
15 |
16 | ## Props
17 |
18 | Click [here](https://clerk.com/docs/components/organization/organization-profile#properties) to see the full list of props available.
19 |
20 | ## Usage
21 |
22 | ```vue
23 |
26 |
27 |
28 |
29 |
30 | ```
31 |
--------------------------------------------------------------------------------
/apps/docs/components/authentication/sign-up.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 |
8 |
9 |
10 | The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in your [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](https://clerk.com/docs/authentication/configuration/sign-up-sign-in-options) and [social connections](https://clerk.com/docs/authentication/social-connections/overview). You can further customize your `` component by passing additional properties at the time of rendering.
11 |
12 | ::: info
13 | The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead.
14 | :::
15 |
16 | ## Props
17 |
18 | Click [here](https://clerk.com/docs/components/authentication/sign-up#properties) to see the full list of props available.
19 |
20 | ## Usage
21 |
22 | Below is basic implementation of the `` component. You can use this as a starting point for your own implementation
23 |
24 | ```vue
25 |
28 |
29 |
30 |
31 |
32 | ```
33 |
--------------------------------------------------------------------------------
/apps/docs/components/authentication/sign-in.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 |
8 |
9 |
10 | The `` component renders a UI for signing in users. The functionality of the `` component is controlled by the instance settings you specify in your [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](https://clerk.com/docs/authentication/configuration/sign-up-sign-in-options) and [social connections](https://clerk.com/docs/authentication/social-connections/overview). You can further customize your `` component by passing additional properties at the time of rendering.
11 |
12 | ::: info
13 | The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead.
14 | :::
15 |
16 | ## Props
17 |
18 | Click [here](https://clerk.com/docs/components/authentication/sign-in#properties) to see the full list of props available.
19 |
20 | ## Usage
21 |
22 | Below is basic implementation of the `` component. You can use this as a starting point for your own implementation.
23 |
24 | ```vue
25 |
28 |
29 |
30 |
31 |
32 | ```
33 |
--------------------------------------------------------------------------------
/apps/docs/.vitepress/components/Banner.vue:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 |
24 |
25 | 🎉 This package has graduated to an official Clerk SDK! See the migration guide.
26 |
27 |
28 |
29 |
30 |
48 |
49 |
73 |
--------------------------------------------------------------------------------
/apps/docs/components/user/user-button.md:
--------------------------------------------------------------------------------
1 | ---
2 | outline: deep
3 | ---
4 |
5 | # ``
6 |
7 |
8 |
9 |
10 | The `` component is used to render the familiar user button UI popularized by Google.
11 |
12 | Clerk is the only provider with multi-session support, allowing users to sign into multiple accounts at once and switch between them. For multisession apps, the `` automatically supports instant account switching, without the need of a full page reload. For more information, you can check out the [Multi-session applications guide](https://clerk.com/docs/custom-flows/multi-session-applications#overview).
13 |
14 | ## Props
15 |
16 | Click [here](https://clerk.com/docs/components/user/user-button#properties) to see the full list of props available.
17 |
18 | ## Usage
19 |
20 | In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu.
21 |
22 | ```vue
23 |
26 |
27 |
28 |
29 |