From e7459ade77753672667c2e603ae887efbd1ca550 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Fri, 15 Nov 2024 17:08:37 -0800 Subject: [PATCH 01/21] feat(nuxt): Add initial quickstart and reference docs --- docs/quickstarts/nuxt.mdx | 165 +++++++++++++++++++++ docs/references/nuxt/overview.mdx | 0 docs/references/nuxt/read-session-data.mdx | 67 +++++++++ 3 files changed, 232 insertions(+) create mode 100644 docs/quickstarts/nuxt.mdx create mode 100644 docs/references/nuxt/overview.mdx create mode 100644 docs/references/nuxt/read-session-data.mdx diff --git a/docs/quickstarts/nuxt.mdx b/docs/quickstarts/nuxt.mdx new file mode 100644 index 0000000000..ba839ffeaa --- /dev/null +++ b/docs/quickstarts/nuxt.mdx @@ -0,0 +1,165 @@ +--- +title: Nuxt Quickstart +description: Add authentication and user management to your Nuxt app with Clerk. +--- + + + - Install `@clerk/nuxt` + - Set your Clerk API keys + - Add module + - Create a header with Clerk components for users to sign in and out + + + + ### Install `@clerk/nuxt` + + Clerk's Nuxt SDK gives you access to prebuilt components, Vue composables, and helpers to make user authentication easier. + + Run the following command to install the SDK: + + + ```bash {{ filename: 'terminal' }} + npm install @clerk/nuxt + ``` + + ```bash {{ filename: 'terminal' }} + yarn add @clerk/nuxt + ``` + + ```bash {{ filename: 'terminal' }} + pnpm add @clerk/nuxt + ``` + + + ### Set your Clerk API keys + + + Add the following keys to your `.env` file. These keys can always be retrieved from the [**API Keys**](https://dashboard.clerk.com/last-active?path=api-keys) page of your Clerk Dashboard. + + + + 1. In the Clerk Dashboard, navigate to the [**API Keys**](https://dashboard.clerk.com/last-active?path=api-keys) page. + 1. In the **Quick Copy** section, copy your Clerk publishable and secret key. + 1. Paste your key into your `.env` file. + + The final result should resemble the following: + + + ```env {{ filename: '.env' }} + NUXT_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} + CLERK_SECRET_KEY={{secret}} + ``` + + ### Update `nuxt.config.ts` + + To enable Clerk in your Nuxt app, add `@clerk/nuxt` to your modules array in `nuxt.config.ts`. + + ```ts {{ filename: 'nuxt.config.ts', mark: [2] }} + export default defineNuxtConfig({ + modules: ['@clerk/nuxt'], + }) + ``` + + ### Protect your pages + + #### Client-side + + To protect your pages on the client-side, you can use Clerk's [prebuilt control components](/docs/components/overview#what-are-control-components) that control the visibility of content based on the user's authentication state. + + The following example uses the following components: + + - [``](/docs/components/control/signed-in): Children of this component can only be seen while **signed in**. + - [``](/docs/components/control/signed-out): Children of this component can only be seen while **signed out**. + - [``](/docs/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. + - [``](/docs/components/unstyled/sign-in-button): An unstyled component that links to the sign-in page or displays the sign-in modal. + + ```vue {{ filename: 'pages/index.vue' }} + + ``` + + #### Server-side + + To protect your API routes, use the `event.context.auth` object in your event handlers. This object contains the `Auth` object that includes the `userId`, allowing you to determine if the user is authenticated. + + ```ts {{ filename: 'server/api/user.ts' }} + export default eventHandler((event) => { + const { userId } = event.context.auth + + if (!userId) { + throw createError({ + statusCode: 401, + statusMessage: 'Unauthorized', + }) + } + + return { userId } + }) + ``` + + ### Create your first user + + Run your project with the following command: + + + ```bash {{ filename: 'terminal' }} + npm run dev + ``` + + ```bash {{ filename: 'terminal' }} + yarn dev + ``` + + ```bash {{ filename: 'terminal' }} + pnpm dev + ``` + + + Visit your app's homepage at [`http://localhost:3000`](http://localhost:3000). Sign up to create your first user. + + +## More resources + +Learn more about Clerk components, how to customize them, and how to use Clerk's client-side helpers using the following guides. + + + - [Read session and user data](/docs/references/nuxt/read-session-data) + - Learn how to use Clerk's composables and helpers to access the active session and user data in your Nuxt app. + + --- + + - [Client-side helpers](/docs/references/nuxt/overview#client-side-helpers) + - Learn more about Nuxt client-side helpers and how to use them. + + --- + + - [Clerk + Nuxt Quickstart Repo](https://github.com/clerk/clerk-nuxt-quickstart) + - The official companion repo for Clerk's Nuxt Quickstart. + diff --git a/docs/references/nuxt/overview.mdx b/docs/references/nuxt/overview.mdx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/references/nuxt/read-session-data.mdx b/docs/references/nuxt/read-session-data.mdx new file mode 100644 index 0000000000..a376c51512 --- /dev/null +++ b/docs/references/nuxt/read-session-data.mdx @@ -0,0 +1,67 @@ +--- +title: Read session and user data in your Nuxt app with Clerk +description: Learn how to use Clerk's composables and helpers to access the active session and user data in your Nuxt application. +--- + +Clerk provides helpers that you can use to access the active session and user data in your Astro application. + +## Server-side + +The following example uses the [`auth()`](/docs/references/nextjs/auth){{ target: '_blank' }} local to validate an authenticated user and the [`currentUser()`](/docs/references/nextjs/current-user){{ target: '_blank' }} local to access the [`Backend API User`](/docs/references/backend/types/backend-user){{ target: '_blank' }} object for the authenticated user. + +```ts {{ filename: 'server/api/me.ts' }} +import { clerkClient } from '@clerk/nuxt/server' + +export default eventHandler(async (event) => { + const { userId } = event.context.auth + + if (!userId) { + throw createError({ + statusCode: 401, + statusMessage: 'Unauthorized', + }) + } + + const user = await clerkClient(event).users.get(event) + + return user +}) +``` + +## Client-side + +### `useAuth()` + +The `useAuth()` composable provides information about the current auth state, as well as helper methods to manage the current active session. The composable returns `userId`, which can be used to protect your pages. + +```vue {{ filename: 'pages/example.vue' }} + + + +``` + +### `useUser()` + +The `useUser()` composable provides the current user's [`User`](/docs/references/javascript/user/user) object, which holds all of the information for a user of your application and provides a set of methods to manage their account. + +```vue {{ filename: 'pages/example.vue' }} + + + +``` From a68f129b0ad247772d9110056a71e2ff5f27808e Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Tue, 19 Nov 2024 16:47:56 -0800 Subject: [PATCH 02/21] chore: More nuxt SDK docs updates --- docs/manifest.json | 44 ++++++++++++++++++++++ docs/quickstarts/nuxt.mdx | 22 +++++------ docs/references/nuxt/overview.mdx | 29 ++++++++++++++ docs/references/nuxt/read-session-data.mdx | 12 +++--- 4 files changed, 90 insertions(+), 17 deletions(-) diff --git a/docs/manifest.json b/docs/manifest.json index e702e9ae58..91b3c87281 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -51,6 +51,11 @@ "tag": "(Beta)", "href": "/docs/quickstarts/tanstack-start", "icon": "tanstack" + }, + { + "title": "Nuxt", + "href": "/docs/quickstarts/nuxt", + "icon": "nuxt" } ] ] @@ -2666,6 +2671,45 @@ ] ] }, + { + "title": "Nuxt", + "collapse": true, + "icon": "nuxt", + "items": [ + [ + { "title": "Overview", "href": "/docs/references/nuxt/overview" }, + { + "title": "Guides", + "items": [ + [ + { + "title": "Read session and user data", + "wrap": false, + "href": "/docs/references/nuxt/read-session-data" + }, + { + "title": "Protecting pages", + "wrap": false, + "href": "/docs/references/nuxt/protecting-pages" + } + ] + ] + }, + { + "title": "General Reference", + "items": [ + [ + { + "title": "`clerkMiddleware()`", + "wrap": false, + "href": "/docs/references/nuxt/clerk-middleware" + } + ] + ] + } + ] + ] + }, { "title": "Vue", "collapse": true, diff --git a/docs/quickstarts/nuxt.mdx b/docs/quickstarts/nuxt.mdx index ba839ffeaa..4d44b486f0 100644 --- a/docs/quickstarts/nuxt.mdx +++ b/docs/quickstarts/nuxt.mdx @@ -63,7 +63,7 @@ description: Add authentication and user management to your Nuxt app with Clerk. ```env {{ filename: '.env' }} NUXT_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} - CLERK_SECRET_KEY={{secret}} + NUXT_CLERK_SECRET_KEY={{secret}} ``` ### Update `nuxt.config.ts` @@ -89,25 +89,25 @@ description: Add authentication and user management to your Nuxt app with Clerk. - [``](/docs/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. - [``](/docs/components/unstyled/sign-in-button): An unstyled component that links to the sign-in page or displays the sign-in modal. - ```vue {{ filename: 'pages/index.vue' }} + ```vue {{ filename: 'app.vue' }} ``` #### Server-side - To protect your API routes, use the `event.context.auth` object in your event handlers. This object contains the `Auth` object that includes the `userId`, allowing you to determine if the user is authenticated. + To protect your API routes, use the `event.context.auth` object in your event handlers. This object exposes the `Auth` object containing the `userId`, allowing you to determine if the user is authenticated. ```ts {{ filename: 'server/api/user.ts' }} export default eventHandler((event) => { diff --git a/docs/references/nuxt/overview.mdx b/docs/references/nuxt/overview.mdx index e69de29bb2..f1eb371360 100644 --- a/docs/references/nuxt/overview.mdx +++ b/docs/references/nuxt/overview.mdx @@ -0,0 +1,29 @@ +--- +title: Nuxt reference overview +description: Learn how to use Clerk to quickly and easily add secure authentication and user management to your Nuxt application. +--- + +Clerk makes it simple to add authentication to your Nuxt application. This documentation covers the capabilities and methods available from Clerk's Nuxt SDK. + +## Guides + +- [Read session and user data](/docs/references/nextjs/read-session-data) + +## Client-side helpers + +Because Clerk Nuxt is a wrapper around Clerk Vue, you can utilize the composables that Clerk Vue provides. These composables give you access to the [`Clerk`](/docs/references/javascript/clerk/clerk) object, and a set of useful helper methods for signing in and signing up. You can learn more about these hooks [in the Vue SDK reference](/docs/references/vue/overview). + +- [`useUser()`](/docs/references/vue/use-user) +- [`useClerk()`](/docs/references/vue/use-clerk) +- [`useAuth()`](/docs/references/vue/use-auth) +- [`useSignIn()`](/docs/references/vue/use-sign-in) +- [`useSignUp()`](/docs/references/vue/use-sign-up) +- [`useSession()`](/docs/references/vue/use-session) +- [`useSessionList()`](/docs/references/vue/use-session-list) +- [`useOrganization()`](/docs/references/vue/use-organization) + +## Other references + +### `Auth` object + +The `Auth` object is available at `event.context.auth` in your [event handlers](https://h3.unjs.io/guide/event-handler). This JavaScript object contains important information like session data, your user's ID, as well as their organization ID. Learn more about the `Auth` object [here](/docs/references/nextjs/auth-object). diff --git a/docs/references/nuxt/read-session-data.mdx b/docs/references/nuxt/read-session-data.mdx index a376c51512..a6855a86e2 100644 --- a/docs/references/nuxt/read-session-data.mdx +++ b/docs/references/nuxt/read-session-data.mdx @@ -3,11 +3,11 @@ title: Read session and user data in your Nuxt app with Clerk description: Learn how to use Clerk's composables and helpers to access the active session and user data in your Nuxt application. --- -Clerk provides helpers that you can use to access the active session and user data in your Astro application. +Clerk provides helpers that you can use to access the active session and user data in your Nuxt application. ## Server-side -The following example uses the [`auth()`](/docs/references/nextjs/auth){{ target: '_blank' }} local to validate an authenticated user and the [`currentUser()`](/docs/references/nextjs/current-user){{ target: '_blank' }} local to access the [`Backend API User`](/docs/references/backend/types/backend-user){{ target: '_blank' }} object for the authenticated user. +The following example uses the `event.context.auth` object to validate an authenticated user and the [`clerkClient`](/docs/references/backend/overview) helper to get the full [`User`](/docs/references/backend/types/backend-user) object. ```ts {{ filename: 'server/api/me.ts' }} import { clerkClient } from '@clerk/nuxt/server' @@ -22,7 +22,7 @@ export default eventHandler(async (event) => { }) } - const user = await clerkClient(event).users.get(event) + const user = await clerkClient(event).users.get(userId) return user }) @@ -36,13 +36,13 @@ The `useAuth()` composable provides information about the current auth state, as ```vue {{ filename: 'pages/example.vue' }} @@ -60,7 +60,7 @@ const { isLoaded, isSignedIn, user } = useUser() From 04a8b092da2e6cb8df22900d191692c0f2fcd7d6 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 11:35:13 -0800 Subject: [PATCH 03/21] docs(nuxt): Add clerkMiddleware reference --- docs/manifest.json | 12 ++++ docs/references/nuxt/clerk-middleware.mdx | 78 ++++++++++++++++++++++ docs/references/nuxt/read-session-data.mdx | 2 +- 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 docs/references/nuxt/clerk-middleware.mdx diff --git a/docs/manifest.json b/docs/manifest.json index 91b3c87281..31e2dc895f 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -2774,6 +2774,18 @@ } ] ] + }, + { + "title": "General Reference", + "items": [ + [ + { + "title": "`clerkMiddleware()`", + "wrap": false, + "href": "/docs/references/nuxt/clerk-middleware" + } + ] + ] } ] ] diff --git a/docs/references/nuxt/clerk-middleware.mdx b/docs/references/nuxt/clerk-middleware.mdx new file mode 100644 index 0000000000..5b635e055a --- /dev/null +++ b/docs/references/nuxt/clerk-middleware.mdx @@ -0,0 +1,78 @@ +--- +title: '`clerkMiddleware()` | Nuxt' +description: The `clerkMiddleware()` function allows you to protect your Nuxt application using Middleware. +--- + +The `clerkMiddleware()` helper integrates Clerk authentication into your Nuxt application through middleware. + +## Configure `clerkMiddleware()` + +By default, the Clerk Nuxt module automatically adds the `clerkMiddleware()` helper to your Nuxt application. If you prefer to manually configure the middleware, you can set `skipServerMiddleware` in your `nuxt.config.ts` under the `clerk` property: + +```ts +export default defineNuxtConfig({ + modules: ['@clerk/nuxt'], + clerk: { + skipServerMiddleware: true, + }, +}) +``` + +Then create a file inside your `server/middleware/` directory: + +```ts {{ filename: 'src/middleware/clerk.ts' }} +import { clerkMiddleware } from '@clerk/nuxt/server' + +export default clerkMiddleware() +``` + +## Protect API routes + +You can protect API routes by checking either or both of the following: + +- [User authentication status](#protect-routes-based-on-user-authentication-status) -- user is signed in or out +- [User authorization status](#protect-routes-based-on-user-authorization-status) -- user has the required role or permission + +### Protect routes based on user authentication status + +To protect routes based on user authentication status, use [`auth.userId`](/docs/references/nextjs/auth#retrieving-user-id){{ target: '_blank' }} to check if the `userId` is present. If it is not, the user is not authenticated, and you can throw an error. + +```tsx {{ filename: 'server/middleware/clerk.ts' }} +import { clerkMiddleware } from '@clerk/nuxt/server' + +export default clerkMiddleware((event) => { + const { userId } = event.context.auth + + if (!userId && event.path.startsWith('/api/user')) { + throw createError({ + statusCode: 401, + statusMessage: 'Unauthorized', + }) + } +}) +``` + +### Protect routes based on user authorization status + +To protect routes based on user authorization status, use [`auth().has()`](/docs/references/nextjs/auth-object#has){{ target: '_blank' }} to check if the user has the required roles or permissions. + +```tsx {{ filename: 'server/middleware/clerk.ts' }} +import { clerkMiddleware } from '@clerk/nuxt/server' + +export default clerkMiddleware((event) => { + const { has } = event.context.auth + + const isAdminRoute = event.path.startsWith('/api/admin') + + // Restrict admin routes to users with specific permissions + if ( + (isAdminRoute && !has({ permission: 'org:sys_memberships:manage' })) || + !has({ permission: 'org:sys_domains_manage' }) + ) { + throw createError({ + statusCode: 403, + statusMessage: 'Forbidden', + }) + } +}) +``` diff --git a/docs/references/nuxt/read-session-data.mdx b/docs/references/nuxt/read-session-data.mdx index a6855a86e2..efd1ff4e00 100644 --- a/docs/references/nuxt/read-session-data.mdx +++ b/docs/references/nuxt/read-session-data.mdx @@ -7,7 +7,7 @@ Clerk provides helpers that you can use to access the active session and user da ## Server-side -The following example uses the `event.context.auth` object to validate an authenticated user and the [`clerkClient`](/docs/references/backend/overview) helper to get the full [`User`](/docs/references/backend/types/backend-user) object. +The following example uses the `auth` event context to validate an authenticated user and the [`clerkClient`](/docs/references/backend/overview) helper to get the full [`User`](/docs/references/backend/types/backend-user) object. ```ts {{ filename: 'server/api/me.ts' }} import { clerkClient } from '@clerk/nuxt/server' From e679860b12cb7f8c0c29598e6c6074eb771d9561 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 11:36:48 -0800 Subject: [PATCH 04/21] docs(nuxt): Add clerkMiddleware link to quickstart --- docs/quickstarts/nuxt.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/quickstarts/nuxt.mdx b/docs/quickstarts/nuxt.mdx index 4d44b486f0..31cb949280 100644 --- a/docs/quickstarts/nuxt.mdx +++ b/docs/quickstarts/nuxt.mdx @@ -150,6 +150,11 @@ description: Add authentication and user management to your Nuxt app with Clerk. Learn more about Clerk components, how to customize them, and how to use Clerk's client-side helpers using the following guides. + - [Protect API routes using Clerk Middleware](/docs/references/nuxt/clerk-middleware) + - Learn how to protect specific API routes from unauthenticated users. + + --- + - [Read session and user data](/docs/references/nuxt/read-session-data) - Learn how to use Clerk's composables and helpers to access the active session and user data in your Nuxt app. From b78489d42ddba3cb2267681de755ac40fdacae93 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 12:24:08 -0800 Subject: [PATCH 05/21] docs(nuxt): Add route middleware example --- docs/references/nuxt/clerk-middleware.mdx | 2 +- docs/references/nuxt/protecting-pages.mdx | 36 +++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 docs/references/nuxt/protecting-pages.mdx diff --git a/docs/references/nuxt/clerk-middleware.mdx b/docs/references/nuxt/clerk-middleware.mdx index 5b635e055a..bf0f900c6e 100644 --- a/docs/references/nuxt/clerk-middleware.mdx +++ b/docs/references/nuxt/clerk-middleware.mdx @@ -9,7 +9,7 @@ The `clerkMiddleware()` helper integrates Clerk authentication into your Nuxt ap By default, the Clerk Nuxt module automatically adds the `clerkMiddleware()` helper to your Nuxt application. If you prefer to manually configure the middleware, you can set `skipServerMiddleware` in your `nuxt.config.ts` under the `clerk` property: -```ts +```ts {{ filename: 'nuxt.config.ts' }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { diff --git a/docs/references/nuxt/protecting-pages.mdx b/docs/references/nuxt/protecting-pages.mdx new file mode 100644 index 0000000000..9495bfdb43 --- /dev/null +++ b/docs/references/nuxt/protecting-pages.mdx @@ -0,0 +1,36 @@ +--- +title: Protecting pages +description: Learn how to protect your Nuxt pages by restricting access to authenticated users using route middleware. +--- + +> [!NOTE] +> Nuxt route middleware (used below) is different from server middleware. Route middleware executes during both server-side render and client-side navigation, making it perfect for protecting pages. If you want to protect API routes instead, check out our guide on [protecting API routes](/docs/references/nuxt/clerk-middleware#protect-api-routes). + +To protect pages, first create a named route middleware that checks the user's authentication status: + +```ts {{ filename: 'middleware/auth.ts' }} +export default defineNuxtRouteMiddleware((to) => { + const { userId } = useAuth() + const isProtectedPage = to.path.startsWith('/dashboard') + + // Redirect to sign-in page if user is not signed in + if (!userId.value && isProtectedPage) { + return navigateTo('/sign-in') + } +}) +``` + +Then, add this middleware configuration to any page that requires protection: + +```vue {{ filename: 'pages/dashboard.vue' }} + + + +``` From 7bc65ed04f85f7eba9d8accd96e5eea3dd8a456d Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 12:29:09 -0800 Subject: [PATCH 06/21] docs(nuxt): Add clerkMiddleware reference to overview --- docs/references/nuxt/overview.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/references/nuxt/overview.mdx b/docs/references/nuxt/overview.mdx index f1eb371360..c1fdf932cb 100644 --- a/docs/references/nuxt/overview.mdx +++ b/docs/references/nuxt/overview.mdx @@ -27,3 +27,7 @@ Because Clerk Nuxt is a wrapper around Clerk Vue, you can utilize the composable ### `Auth` object The `Auth` object is available at `event.context.auth` in your [event handlers](https://h3.unjs.io/guide/event-handler). This JavaScript object contains important information like session data, your user's ID, as well as their organization ID. Learn more about the `Auth` object [here](/docs/references/nextjs/auth-object). + +### `clerkMiddleware()` + +The `clerkMiddleware()` helper integrates Clerk authentication and authorization into your Nuxt application through middleware. You can learn more [here](/docs/references/nuxt/clerk-middleware). From 026108af75ec93710d0b2f8c223237249279b9dd Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 13:09:19 -0800 Subject: [PATCH 07/21] docs(nuxt): Add quickstart overview and homepage entry --- docs/index.mdx | 5 +++++ docs/quickstarts/overview.mdx | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/docs/index.mdx b/docs/index.mdx index 554829ae3a..8c13e6568f 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -81,9 +81,14 @@ Find all the guides and resources you need to develop with Clerk. --- +<<<<<<< HEAD - [React Router (Beta)](/docs/quickstarts/react-router) - Easily add secure, edge- and SSR-friendly authentication to React Router with Clerk. - {} +======= + - [Nuxt](/docs/quickstarts/nuxt) + - Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. +>>>>>>> a7d697c2 (docs(nuxt): Add quickstart overview and homepage entry) ## Explore by backend framework diff --git a/docs/quickstarts/overview.mdx b/docs/quickstarts/overview.mdx index 498b62fe6f..83c5505c56 100644 --- a/docs/quickstarts/overview.mdx +++ b/docs/quickstarts/overview.mdx @@ -33,6 +33,11 @@ description: See the getting started guides and tutorials. - [TanStack Start (Beta)](/docs/quickstarts/tanstack-start) - Easily add secure and SSR-friendly authentication to your TanStack Start application with Clerk. - ![](data:image/webp;base64,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) + + --- + + - [Nuxt](/docs/quickstarts/nuxt) + - Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. ## Frontend From a81cc4a7c0b0b003f4c089dca70535ef6625f014 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 13:44:52 -0800 Subject: [PATCH 08/21] add placeholder icon --- docs/manifest.schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/manifest.schema.json b/docs/manifest.schema.json index 1909c9e4e3..3773be9eef 100644 --- a/docs/manifest.schema.json +++ b/docs/manifest.schema.json @@ -139,7 +139,8 @@ "user-dotted-circle", "vue", "x", - "expo" + "expo", + "nuxt" ] } } From 317f0a266294878fe028cc7be7f8e69af3f983d0 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 13:57:16 -0800 Subject: [PATCH 09/21] add nuxt svgs --- docs/index.mdx | 4 ++++ docs/quickstarts/overview.mdx | 1 + 2 files changed, 5 insertions(+) diff --git a/docs/index.mdx b/docs/index.mdx index 8c13e6568f..a65f6ed634 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -88,7 +88,11 @@ Find all the guides and resources you need to develop with Clerk. ======= - [Nuxt](/docs/quickstarts/nuxt) - Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. +<<<<<<< HEAD >>>>>>> a7d697c2 (docs(nuxt): Add quickstart overview and homepage entry) +======= + - {} +>>>>>>> a9703b04 (add nuxt svgs) ## Explore by backend framework diff --git a/docs/quickstarts/overview.mdx b/docs/quickstarts/overview.mdx index 83c5505c56..c040f56e68 100644 --- a/docs/quickstarts/overview.mdx +++ b/docs/quickstarts/overview.mdx @@ -38,6 +38,7 @@ description: See the getting started guides and tutorials. - [Nuxt](/docs/quickstarts/nuxt) - Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. + - {} ## Frontend From b180c9b3ad6071eef9dbb7c6aeec65bbfcf95849 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 15:30:30 -0800 Subject: [PATCH 10/21] docs(nuxt): Add backend references for clerkClient --- docs/references/backend/overview.mdx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/references/backend/overview.mdx b/docs/references/backend/overview.mdx index 48a87d65a9..8addf773da 100644 --- a/docs/references/backend/overview.mdx +++ b/docs/references/backend/overview.mdx @@ -60,7 +60,7 @@ To access a resource, you must first instantiate a `clerkClient` instance. To use the default `clerkClient` instance, set your `CLERK_SECRET_KEY` [environment variable](/docs/deployments/clerk-environment-variables#clerk-publishable-and-secret-keys) and then import the `clerkClient` instance from the SDK as shown in the following example: - + ```jsx import { clerkClient } from '@clerk/nextjs/server' @@ -88,13 +88,19 @@ To access a resource, you must first instantiate a `clerkClient` instance. import { clerkClient } from '@clerk/express' ``` + + + ```js + import { clerkClient } from '@clerk/nuxt/server' + ``` + ### Instantiate a custom `clerkClient` instance If you would like to customize the behavior of the JavaScript Backend SDK, you can instantiate a `clerkClient` instance yourself by calling `createClerkClient()` and passing in [`options`](#create-clerk-client-options). - + ```jsx import { createClerkClient } from '@clerk/nextjs/server' @@ -243,6 +249,21 @@ To access a resource, you must first instantiate a `clerkClient` instance. ``` + + + ```tsx {{ filename: 'server/api/example.ts' }} + import { createClerkClient } from '@clerk/nuxt/express' + + export default eventHandler((event) => { + const config = useRuntimeConfig() + const clerkClient = createClerkClient({ secretKey: config.clerk.secretKey }) + + const userList = await clerkClient.users.getUserList() + + return { userList } + }) + ``` + From d189d22f7b7bfa1483e5f141e22fd5c268085a61 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 20 Nov 2024 15:32:18 -0800 Subject: [PATCH 11/21] docs(nuxt): Add missing async keyword --- docs/references/backend/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/backend/overview.mdx b/docs/references/backend/overview.mdx index 8addf773da..ea15061bc1 100644 --- a/docs/references/backend/overview.mdx +++ b/docs/references/backend/overview.mdx @@ -254,7 +254,7 @@ To access a resource, you must first instantiate a `clerkClient` instance. ```tsx {{ filename: 'server/api/example.ts' }} import { createClerkClient } from '@clerk/nuxt/express' - export default eventHandler((event) => { + export default eventHandler(async (event) => { const config = useRuntimeConfig() const clerkClient = createClerkClient({ secretKey: config.clerk.secretKey }) From feb14631ede3d094e751c5dada31f86fb835d3a3 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Thu, 21 Nov 2024 17:21:40 +0000 Subject: [PATCH 12/21] make nuxt icon a bit bigger --- docs/index.mdx | 4 ++++ docs/quickstarts/overview.mdx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/index.mdx b/docs/index.mdx index a65f6ed634..8a77fb0cc9 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -89,10 +89,14 @@ Find all the guides and resources you need to develop with Clerk. - [Nuxt](/docs/quickstarts/nuxt) - Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> a7d697c2 (docs(nuxt): Add quickstart overview and homepage entry) ======= - {} >>>>>>> a9703b04 (add nuxt svgs) +======= + - {} +>>>>>>> 9a251fea (make nuxt icon a bit bigger) ## Explore by backend framework diff --git a/docs/quickstarts/overview.mdx b/docs/quickstarts/overview.mdx index c040f56e68..70cd54e47a 100644 --- a/docs/quickstarts/overview.mdx +++ b/docs/quickstarts/overview.mdx @@ -38,7 +38,7 @@ description: See the getting started guides and tutorials. - [Nuxt](/docs/quickstarts/nuxt) - Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. - - {} + - {} ## Frontend From 47e4bc63fef82af7df5783f4b5fb35d3259198ef Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Thu, 21 Nov 2024 09:57:47 -0800 Subject: [PATCH 13/21] docs(nuxt): Fix example for protecting pages --- docs/references/nuxt/protecting-pages.mdx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/references/nuxt/protecting-pages.mdx b/docs/references/nuxt/protecting-pages.mdx index 9495bfdb43..e3a9964238 100644 --- a/docs/references/nuxt/protecting-pages.mdx +++ b/docs/references/nuxt/protecting-pages.mdx @@ -4,23 +4,22 @@ description: Learn how to protect your Nuxt pages by restricting access to authe --- > [!NOTE] -> Nuxt route middleware (used below) is different from server middleware. Route middleware executes during both server-side render and client-side navigation, making it perfect for protecting pages. If you want to protect API routes instead, check out our guide on [protecting API routes](/docs/references/nuxt/clerk-middleware#protect-api-routes). +> This page covers protecting pages. For protecting API routes instead, see our guide on [protecting API routes](/docs/references/nuxt/clerk-middleware#protect-api-routes). To protect pages, first create a named route middleware that checks the user's authentication status: ```ts {{ filename: 'middleware/auth.ts' }} -export default defineNuxtRouteMiddleware((to) => { +export default defineNuxtRouteMiddleware(() => { const { userId } = useAuth() - const isProtectedPage = to.path.startsWith('/dashboard') // Redirect to sign-in page if user is not signed in - if (!userId.value && isProtectedPage) { + if (!userId.value) { return navigateTo('/sign-in') } }) ``` -Then, add this middleware configuration to any page that requires protection: +Then, add the middleware to any page that requires protection: ```vue {{ filename: 'pages/dashboard.vue' }} + ``` - #### Server-side + ## Protect your API routes + + API routes in Nuxt 3 are handled by [`eventHandler`](https://nuxt.com/docs/guide/directory-structure/server) functions in the `server/api` directory. Files in this directory automatically become API endpoints matching their path (e.g., `server/api/user.ts` becomes `/api/user`). + + To protect your API routes, use the `event.context.auth` object in your event handlers. This object is automatically injected by Clerk and contains authentication information about the current request. - To protect your API routes, use the `event.context.auth` object in your event handlers. This object exposes the `Auth` object containing the `userId`, allowing you to determine if the user is authenticated. + The following example protects an API route by checking if a user is authenticated. If the user isn't authenticated, the route returns a 401 Unauthorized error. - ```ts {{ filename: 'server/api/user.ts' }} - export default eventHandler((event) => { + ```ts {{ filename: 'server/api/auth/index.ts' }} + export default defineEventHandler((event) => { const { userId } = event.context.auth if (!userId) { @@ -129,7 +139,7 @@ description: Add authentication and user management to your Nuxt app with Clerk. }) ``` - ### Create your first user + ## Create your first user Run your project with the following command: diff --git a/docs/references/backend/overview.mdx b/docs/references/backend/overview.mdx index 4340527d8b..492372dad2 100644 --- a/docs/references/backend/overview.mdx +++ b/docs/references/backend/overview.mdx @@ -251,13 +251,12 @@ To access a resource, you must first instantiate a `clerkClient` instance. - ```tsx {{ filename: 'server/api/example.ts' }} + ```tsx {{ filename: 'server/api/users/index.ts' }} import { createClerkClient } from '@clerk/nuxt/server' - export default eventHandler(async (event) => { + export default defineEventHandler(async () => { const config = useRuntimeConfig() const clerkClient = createClerkClient({ secretKey: config.clerk.secretKey }) - const userList = await clerkClient.users.getUserList() return { userList } diff --git a/docs/references/nuxt/clerk-middleware.mdx b/docs/references/nuxt/clerk-middleware.mdx index bf0f900c6e..93ad3a9a9c 100644 --- a/docs/references/nuxt/clerk-middleware.mdx +++ b/docs/references/nuxt/clerk-middleware.mdx @@ -1,78 +1,118 @@ --- -title: '`clerkMiddleware()` | Nuxt' -description: The `clerkMiddleware()` function allows you to protect your Nuxt application using Middleware. +title: Protecting API routes with clerkMiddleware() | Nuxt +description: Learn how to protect your Nuxt API routes using Clerk's middleware. --- -The `clerkMiddleware()` helper integrates Clerk authentication into your Nuxt application through middleware. +The `clerkMiddleware()` helper integrates Clerk authentication into your Nuxt application through middleware to protect API routes by validating authentication server-side. You can protect API routes based on user authentication status or authorization status. + +To learn how to protect pages, see the [dedicated guide](/docs/references/nuxt/protecting-pages). ## Configure `clerkMiddleware()` -By default, the Clerk Nuxt module automatically adds the `clerkMiddleware()` helper to your Nuxt application. If you prefer to manually configure the middleware, you can set `skipServerMiddleware` in your `nuxt.config.ts` under the `clerk` property: +By default, the Nuxt SDK **automatically** adds the `clerkMiddleware()` helper to your Nuxt application. -```ts {{ filename: 'nuxt.config.ts' }} -export default defineNuxtConfig({ - modules: ['@clerk/nuxt'], - clerk: { - skipServerMiddleware: true, - }, -}) -``` +To **manually** configure the middleware: -Then create a file inside your `server/middleware/` directory: +1. In your `nuxt.config.ts` file, set `skipServerMiddleware: true` under the `clerk` property. -```ts {{ filename: 'src/middleware/clerk.ts' }} -import { clerkMiddleware } from '@clerk/nuxt/server' + ```ts {{ filename: 'nuxt.config.ts', mark: [[3, 5]] }} + export default defineNuxtConfig({ + modules: ['@clerk/nuxt'], + clerk: { + skipServerMiddleware: true, + }, + }) + ``` +1. In your `server/middleware/` directory, create a file named `clerk.ts`: -export default clerkMiddleware() -``` + ```ts {{ filename: 'src/middleware/clerk.ts' }} + import { clerkMiddleware } from '@clerk/nuxt/server' + export default clerkMiddleware() + ``` + +## Protecting API routes with `clerkMiddleware()` -## Protect API routes +You can protect routes using either or both of the following: -You can protect API routes by checking either or both of the following: +- [Authentication-based protection](#authentication-based-protection): Verify if the user is signed in +- [Authorization-based protection](#authorization-based-protection): Verify if the user has the required organization roles or custom permissions -- [User authentication status](#protect-routes-based-on-user-authentication-status) -- user is signed in or out -- [User authorization status](#protect-routes-based-on-user-authorization-status) -- user has the required role or permission +### Authentication-based protection -### Protect routes based on user authentication status +To protect routes based on user authentication status, you can check if the user is signed in by accessing the `userId` on the `auth` object. -To protect routes based on user authentication status, use [`auth.userId`](/docs/references/nextjs/auth#retrieving-user-id){{ target: '_blank' }} to check if the `userId` is present. If it is not, the user is not authenticated, and you can throw an error. +In the following example, the `clerkMiddleware()` helper verifies if the user is accessing an authenticated route. If the user is not signed in, an error is thrown using Nuxt's [`createError`](https://nuxt.com/docs/api/utils/create-error) utility. ```tsx {{ filename: 'server/middleware/clerk.ts' }} import { clerkMiddleware } from '@clerk/nuxt/server' export default clerkMiddleware((event) => { const { userId } = event.context.auth + const isAdminRoute = event.path.startsWith('/api/admin') - if (!userId && event.path.startsWith('/api/user')) { + // Check if the user is trying to access a protected route without authentication + if (!userId && isAdminRoute) { throw createError({ statusCode: 401, - statusMessage: 'Unauthorized', + statusMessage: 'Unauthorized: User not signed in', }) } }) ``` -### Protect routes based on user authorization status +### Authorization-based protection -To protect routes based on user authorization status, use [`auth().has()`](/docs/references/nextjs/auth-object#has){{ target: '_blank' }} to check if the user has the required roles or permissions. +To protect routes based on user authorization status, you can check if the user has the required organization roles or permissions. Organizations have two default roles: **Admin** (`org:admin`) and **Member** (`org:member`). You can also create custom roles and permissions. See the [dedicated guide](/docs/organizations/roles-permissions#permissions). -```tsx {{ filename: 'server/middleware/clerk.ts' }} +#### Protecting routes using default roles + +In the following example, the `clerkMiddleware()` helper verifies if the user is accessing an admin route. If so, it checks the `userId` and `orgRole` properties to ensure the user is both signed in and has the required admin role. If either check fails, an error is thrown using Nuxt's [`createError`](https://nuxt.com/docs/api/utils/create-error) utility. + +```ts {{ filename: 'server/middleware/clerk.ts' }} import { clerkMiddleware } from '@clerk/nuxt/server' export default clerkMiddleware((event) => { - const { has } = event.context.auth - + const { userId, orgRole } = event.context.auth const isAdminRoute = event.path.startsWith('/api/admin') - // Restrict admin routes to users with specific permissions - if ( - (isAdminRoute && !has({ permission: 'org:sys_memberships:manage' })) || - !has({ permission: 'org:sys_domains_manage' }) - ) { - throw createError({ - statusCode: 403, - statusMessage: 'Forbidden', - }) + // Check if the user is trying to access a protected route + if (isAdminRoute) { + // Check if the user is signed in and has the required admin role + if (!userId || orgRole !== 'org:admin') { + throw createError({ + statusCode: 403, + statusMessage: 'Forbidden: Admin access required', + }) + } + } +}) +``` + +#### Protecting routes using custom permissions + +System permissions (e.g., `org:sys_domains:manage`) aren't included in session claims and can't be used with `auth.has()` on the server-side. To perform permission checks in middleware, **you must create and use custom permissions**. See the [dedicated guide](/docs/organizations/roles-permissions#permissions). + +In the following example, the `clerkMiddleware()` helper verifies if the user is accessing an invoices route. If so, it checks if the user has the required custom permission. If not, an error is thrown using Nuxt's [`createError`](https://nuxt.com/docs/api/utils/create-error) utility. + +```ts {{ filename: 'server/middleware/clerk.ts' }} +import { clerkMiddleware } from '@clerk/nuxt/server' + +export default clerkMiddleware((event) => { + const { has } = event.context.auth + const isInvoicesRoute = event.path.startsWith('/api/invoices') + const canCreateInvoices = has({ + permission: 'org:invoices:create', + }) + + // Check if user is accessing sensitive customer data + if (isInvoicesRoute) { + // Check if user has the required permission + if (!canCreateInvoices) { + throw createError({ + statusCode: 403, + statusMessage: 'Forbidden: Missing invoice creation permission', + }) + } } }) ``` diff --git a/docs/references/nuxt/overview.mdx b/docs/references/nuxt/overview.mdx index 273a13a6d6..4a2a5e60dd 100644 --- a/docs/references/nuxt/overview.mdx +++ b/docs/references/nuxt/overview.mdx @@ -1,9 +1,9 @@ --- -title: Nuxt reference overview -description: Learn how to use Clerk to quickly and easily add secure authentication and user management to your Nuxt application. +title: Clerk Nuxt SDK +description: Learn how to integrate Clerk into your Nuxt application using the Clerk Nuxt SDK. --- -Clerk makes it simple to add authentication to your Nuxt application. This documentation covers the capabilities and methods available from Clerk's Nuxt SDK. +The Nuxt SDK is built on top of the [Vue SDK](/docs/references/vue/overview), and is the recommended method for integrating Clerk into your Nuxt application. ## Guides @@ -12,7 +12,7 @@ Clerk makes it simple to add authentication to your Nuxt application. This docum ## Client-side helpers -Because Clerk Nuxt is a wrapper around Clerk Vue, you can utilize the composables that Clerk Vue provides. These composables give you access to the [`Clerk`](/docs/references/javascript/clerk/clerk) object, and a set of useful helper methods for signing in and signing up. You can learn more about these hooks [in the Vue SDK reference](/docs/references/vue/overview). +The Nuxt SDK provides composables that give you access to the [`Clerk`](/docs/references/javascript/clerk/clerk) object and helper methods for authentication flows. See the [Vue SDK reference](/docs/references/vue/overview) for details. - [`useUser()`](/docs/references/vue/use-user) - [`useClerk()`](/docs/references/vue/use-clerk) @@ -23,7 +23,9 @@ Because Clerk Nuxt is a wrapper around Clerk Vue, you can utilize the composable - [`useSessionList()`](/docs/references/vue/use-session-list) - [`useOrganization()`](/docs/references/vue/use-organization) -## Other references +## Server-side helpers + +The following references show how to integrate Clerk features into applications using Nuxt server functions and API routes. ### `Auth` object diff --git a/docs/references/nuxt/protecting-pages.mdx b/docs/references/nuxt/protecting-pages.mdx index fd2fa48d1e..48bc47573e 100644 --- a/docs/references/nuxt/protecting-pages.mdx +++ b/docs/references/nuxt/protecting-pages.mdx @@ -1,30 +1,35 @@ --- -title: Protecting pages -description: Learn how to protect your Nuxt pages by restricting access to authenticated users using route middleware. +title: Protecting pages with defineNuxtRouteMiddleware() | Nuxt +description: Learn how to protect your Nuxt pages using Nuxt's utility function. --- -> [!NOTE] -> This page covers protecting pages. For API routes, see our [separate guide](/docs/references/nuxt/clerk-middleware#protect-api-routes). +The [`defineNuxtRouteMiddleware()`](https://nuxt.com/docs/api/utils/define-nuxt-route-middleware) utility function integrates Clerk authentication into your Nuxt application through middleware to protect pages by validating authentication client-side. You can use this utility to protect pages based on user authentication status. -To protect pages, first create a named route middleware that checks the user's authentication status: +To learn how to protect API routes, see the [dedicated guide](/docs/references/nuxt/clerk-middleware#protect-api-routes). + +## Configure `defineNuxtRouteMiddleware()` + +1. In your `middleware/` directory, create a file named `auth.ts`: ```ts {{ filename: 'middleware/auth.ts' }} export default defineNuxtRouteMiddleware(() => { const { userId } = useAuth() - // Redirect to sign-in page if user is not signed in + // If the user is not signed in, redirect to the sign-in page if (!userId.value) { return navigateTo('/sign-in') } }) ``` -Then, add the middleware to any page that requires protection: +## Protecting pages with `defineNuxtRouteMiddleware()` + +1. In your `pages` directory, create a page named `dashboard.vue`. This page should be accessible only to authenticated users: ```vue {{ filename: 'pages/dashboard.vue' }} diff --git a/docs/references/nuxt/read-session-data.mdx b/docs/references/nuxt/read-session-data.mdx index efd1ff4e00..4e95a23ea3 100644 --- a/docs/references/nuxt/read-session-data.mdx +++ b/docs/references/nuxt/read-session-data.mdx @@ -3,65 +3,68 @@ title: Read session and user data in your Nuxt app with Clerk description: Learn how to use Clerk's composables and helpers to access the active session and user data in your Nuxt application. --- -Clerk provides helpers that you can use to access the active session and user data in your Nuxt application. - -## Server-side - -The following example uses the `auth` event context to validate an authenticated user and the [`clerkClient`](/docs/references/backend/overview) helper to get the full [`User`](/docs/references/backend/types/backend-user) object. - -```ts {{ filename: 'server/api/me.ts' }} -import { clerkClient } from '@clerk/nuxt/server' - -export default eventHandler(async (event) => { - const { userId } = event.context.auth - - if (!userId) { - throw createError({ - statusCode: 401, - statusMessage: 'Unauthorized', - }) - } - - const user = await clerkClient(event).users.get(userId) - - return user -}) -``` +Clerk provides [composables and helpers](/docs/references/nuxt/overview#client-side-helpers) to access the session and user data in your Nuxt application. ## Client-side -### `useAuth()` +### How to use the `useAuth()` composable + +The `useAuth()` composable provides access to the current authentication state and methods to manage the active session. You can use this composable to protect [routes](/docs/references/nuxt/clerk-middleware) or [pages](/docs/references/nuxt/protecting-pages). -The `useAuth()` composable provides information about the current auth state, as well as helper methods to manage the current active session. The composable returns `userId`, which can be used to protect your pages. +In the following example, the `useAuth()` composable is used to access the current authentication state. The `isLoaded` property checks if Clerk has finished initializing, and the `userId` property returns the ID of the currently signed in user, or `null` if no user is signed in. -```vue {{ filename: 'pages/example.vue' }} +```vue {{ filename: 'pages/protected-page.vue' }} ``` -### `useUser()` +## How to use the `useUser()` composable -The `useUser()` composable provides the current user's [`User`](/docs/references/javascript/user/user) object, which holds all of the information for a user of your application and provides a set of methods to manage their account. +The `useUser()` composable provides access to the current user's [`User`](/docs/references/javascript/user/user) object, which holds all of the data for a user of your application and provides a set of methods to manage their account. -```vue {{ filename: 'pages/example.vue' }} +In the following example, the `useUser()` composable is used to access the current user's data. The `isLoaded` property checks if Clerk has finished initializing, and the `isSignedIn` property checks if a user is currently signed in. If the user is signed in, display the user's first name from the `user` property. + +```vue {{ filename: 'pages/protected-page.vue' }} ``` + +## Server-Side + +### How to use the `clerkClient()` helper + +In the following example, the `auth` object is used to get the `userId` to check if the user is signed in. The [`clerkClient()`](/docs/references/backend/overview#clerkclient) helper retrieves the full [`User`](/docs/references/javascript/user/user) object. + +```ts {{ filename: 'server/api/auth/index.ts' }} +import { clerkClient } from '@clerk/nuxt/server' + +export default defineEventHandler(async (event) => { + const { userId } = event.context.auth + + // Check if the user is signed in + if (!userId) { + throw createError({ + statusCode: 401, + statusMessage: 'Unauthorized: No user ID provided', + }) + } + + // Retrieve the user data + const user = await clerkClient(event).users.getUser(userId) + return user +}) +``` From 50e50731f3c40bdbd0e49c68644e87364b0ef232 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Thu, 19 Dec 2024 18:01:13 -0500 Subject: [PATCH 20/21] docs review --- docs/_partials/nuxt/use-auth.mdx | 15 +++++ docs/manifest.json | 4 +- docs/quickstarts/nuxt.mdx | 31 ++------- docs/references/backend/overview.mdx | 2 +- docs/references/nuxt/clerk-middleware.mdx | 73 ++++++++++++---------- docs/references/nuxt/overview.mdx | 16 ++--- docs/references/nuxt/protect-pages.mdx | 54 ++++++++++++++++ docs/references/nuxt/protecting-pages.mdx | 40 ------------ docs/references/nuxt/read-session-data.mdx | 34 ++++------ 9 files changed, 134 insertions(+), 135 deletions(-) create mode 100644 docs/_partials/nuxt/use-auth.mdx create mode 100644 docs/references/nuxt/protect-pages.mdx delete mode 100644 docs/references/nuxt/protecting-pages.mdx diff --git a/docs/_partials/nuxt/use-auth.mdx b/docs/_partials/nuxt/use-auth.mdx new file mode 100644 index 0000000000..10be5d3743 --- /dev/null +++ b/docs/_partials/nuxt/use-auth.mdx @@ -0,0 +1,15 @@ +The `useAuth()` composable provides access to the current authentication state and methods to manage the active session. You can use this composable to protect [pages](/docs/references/nuxt/protect-pages). + +In the following example, the `isLoaded` property checks if Clerk has finished initializing and the `userId` property checks if the user is signed in. + +```vue {{ filename: 'pages/protected-page.vue' }} + + + +``` diff --git a/docs/manifest.json b/docs/manifest.json index 3e2f112186..4e10710e15 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -2713,9 +2713,9 @@ "href": "/docs/references/nuxt/read-session-data" }, { - "title": "Protecting pages", + "title": "Protect pages", "wrap": false, - "href": "/docs/references/nuxt/protecting-pages" + "href": "/docs/references/nuxt/protect-pages" } ] ] diff --git a/docs/quickstarts/nuxt.mdx b/docs/quickstarts/nuxt.mdx index 7465c29492..452360020f 100644 --- a/docs/quickstarts/nuxt.mdx +++ b/docs/quickstarts/nuxt.mdx @@ -74,7 +74,7 @@ description: Add authentication and user management to your Nuxt app with Clerk. ## Configure `nuxt.config.ts` - To enable Clerk in your Nuxt app, add `@clerk/nuxt` to your modules array in `nuxt.config.ts`. This automatically configures Clerk's middleware and plugins, and imports Clerk's components. + To enable Clerk in your Nuxt app, add `@clerk/nuxt` to your modules array in `nuxt.config.ts`. This automatically configures Clerk's middleware and plugins and imports Clerk's components. ```ts {{ filename: 'nuxt.config.ts', mark: [2] }} export default defineNuxtConfig({ @@ -84,7 +84,7 @@ description: Add authentication and user management to your Nuxt app with Clerk. ## Create a header with Clerk components - [Nuxt 3](https://nuxt.com/docs/migration/auto-imports) automatically imports and makes available all components in the `components/` directory globally, without requiring explicit imports. See the [Nuxt docs](https://nuxt.com/docs/guide/concepts/auto-imports) for details. + Nuxt 3 automatically imports and makes all components in the `components/` directory globally available without requiring explicit imports. See the [Nuxt docs](https://nuxt.com/docs/guide/concepts/auto-imports) for details. You can control which content signed-in and signed-out users can see with Clerk's [prebuilt control components](/docs/components/overview#what-are-control-components). @@ -93,7 +93,7 @@ description: Add authentication and user management to your Nuxt app with Clerk. - [``](/docs/components/control/signed-in): Children of this component can only be seen while **signed in**. - [``](/docs/components/control/signed-out): Children of this component can only be seen while **signed out**. - [``](/docs/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. - - [``](/docs/components/unstyled/sign-in-button): An unstyled component that links to the sign-in page or displays the sign-in modal. + - [``](/docs/components/unstyled/sign-in-button): An unstyled component that links to the sign-in page or displays the sign-in modal. In this example, since no props or [environment variables](/docs/deployments/clerk-environment-variables) are set for the sign-in URL, this component links to the [Account Portal sign-in page](/docs/customization/account-portal/overview#sign-in). ```vue {{ filename: 'app.vue', mark: [2, [6, 13]] }} + + + ``` + diff --git a/docs/references/nuxt/protecting-pages.mdx b/docs/references/nuxt/protecting-pages.mdx deleted file mode 100644 index 48bc47573e..0000000000 --- a/docs/references/nuxt/protecting-pages.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Protecting pages with defineNuxtRouteMiddleware() | Nuxt -description: Learn how to protect your Nuxt pages using Nuxt's utility function. ---- - -The [`defineNuxtRouteMiddleware()`](https://nuxt.com/docs/api/utils/define-nuxt-route-middleware) utility function integrates Clerk authentication into your Nuxt application through middleware to protect pages by validating authentication client-side. You can use this utility to protect pages based on user authentication status. - -To learn how to protect API routes, see the [dedicated guide](/docs/references/nuxt/clerk-middleware#protect-api-routes). - -## Configure `defineNuxtRouteMiddleware()` - -1. In your `middleware/` directory, create a file named `auth.ts`: - -```ts {{ filename: 'middleware/auth.ts' }} -export default defineNuxtRouteMiddleware(() => { - const { userId } = useAuth() - - // If the user is not signed in, redirect to the sign-in page - if (!userId.value) { - return navigateTo('/sign-in') - } -}) -``` - -## Protecting pages with `defineNuxtRouteMiddleware()` - -1. In your `pages` directory, create a page named `dashboard.vue`. This page should be accessible only to authenticated users: - -```vue {{ filename: 'pages/dashboard.vue' }} - - - -``` diff --git a/docs/references/nuxt/read-session-data.mdx b/docs/references/nuxt/read-session-data.mdx index 4e95a23ea3..f01f0939ec 100644 --- a/docs/references/nuxt/read-session-data.mdx +++ b/docs/references/nuxt/read-session-data.mdx @@ -1,35 +1,21 @@ --- title: Read session and user data in your Nuxt app with Clerk -description: Learn how to use Clerk's composables and helpers to access the active session and user data in your Nuxt application. +description: Learn how to use Clerk's composables to access the active session and user data in your Nuxt application. --- -Clerk provides [composables and helpers](/docs/references/nuxt/overview#client-side-helpers) to access the session and user data in your Nuxt application. +Clerk provides [composables](/docs/references/nuxt/overview#client-side-helpers) to access the session and user data in your Nuxt application. ## Client-side -### How to use the `useAuth()` composable +### `useAuth()` -The `useAuth()` composable provides access to the current authentication state and methods to manage the active session. You can use this composable to protect [routes](/docs/references/nuxt/clerk-middleware) or [pages](/docs/references/nuxt/protecting-pages). + -In the following example, the `useAuth()` composable is used to access the current authentication state. The `isLoaded` property checks if Clerk has finished initializing, and the `userId` property returns the ID of the currently signed in user, or `null` if no user is signed in. - -```vue {{ filename: 'pages/protected-page.vue' }} - - - -``` - -## How to use the `useUser()` composable +## `useUser()` The `useUser()` composable provides access to the current user's [`User`](/docs/references/javascript/user/user) object, which holds all of the data for a user of your application and provides a set of methods to manage their account. -In the following example, the `useUser()` composable is used to access the current user's data. The `isLoaded` property checks if Clerk has finished initializing, and the `isSignedIn` property checks if a user is currently signed in. If the user is signed in, display the user's first name from the `user` property. +In the following example, the `isLoaded` property checks if Clerk has finished initializing and the `isSignedIn` property checks if a user is currently signed in. ```vue {{ filename: 'pages/protected-page.vue' }}