All skills
clerk avatar

/clerk-nuxt-patterns

@ca5e365 official
by clerkclerk/skills83 stars
5

Nuxt 3 auth patterns with @clerk/nuxt - middleware, composables, server API routes, SSR. Triggers on: Nuxt auth, useAuth composable, clerkMiddleware Nuxt, server API Clerk, Nuxt route protection.

Use this Skill: https://skilld.dev/gh/clerk/skills/clerk-nuxt-patterns

This session only. Nothing lands on disk.

referencesssr-auth.md

≈539 tokens on demand. Your agent reads this file only when SKILL.md points to it.

SSR Auth (HIGH)

Server vs Client Boundary

@clerk/nuxt composables (useAuth, useUser) are client-reactive but the initial state is SSR-safe.

Context How to get auth
Vue component (<script setup>) useAuth(), useUser() composables
Nitro server route event.context.auth
Nuxt plugin (server) event.context.auth via useNitroApp

SSR-Safe Page Pattern

<script setup lang="ts">
definePageMeta({ middleware: 'auth' })
const { userId, isLoaded } = useAuth()
</script>

<template>
  <div v-if="!isLoaded">Loading...</div>
  <main v-else>
    <p>User: {{ userId }}</p>
  </main>
</template>

The middleware runs server-side, so by the time the page renders, unauthenticated users are already redirected.

Hydration Safety

Avoid rendering auth-dependent content that differs between server and client:

<!-- WRONG: causes hydration mismatch -->
<template>
  <div v-if="isSignedIn">Dashboard</div>
</template>

<!-- CORRECT: use ClientOnly for auth-gated content if SSR causes mismatch -->
<template>
  <ClientOnly>
    <div v-if="isSignedIn">Dashboard</div>
  </ClientOnly>
</template>

When using middleware, the server redirect happens before hydration, so this is rarely needed for protected pages.

useFetch with Auth

Pass the session token to server-side useFetch for authenticated API calls:

<script setup lang="ts">
const { getToken } = useAuth()

const { data } = await useFetch('/api/protected', {
  headers: async () => {
    const token = await getToken()
    return token ? { Authorization: `Bearer ${token}` } : {}
  },
})
</script>

Pinia State Hydration

When using Pinia with Clerk, hydrate the store with server auth state to avoid client-side flash:

// plugins/auth-hydration.ts
import { useAuthStore } from '@/stores/auth'

export default defineNuxtPlugin(async () => {
  const store = useAuthStore()
  await until(store.isLoaded).toBeTruthy()
})

Stores are created per-request on the server — do NOT store sensitive data (tokens) in Pinia.

Docs

Source: SKILL.md on GitHub

No alerts16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides legitimate Nuxt 3 authentication patterns using the official Clerk SDK. All code snippets, configurations, and dependencies follow established best practices for secure application development.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at ca5e365. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 6 months ago
What it can do
Network
metadata
{
  "author": "clerk",
  "version": "1.0.0"
}
All 1 allowed tools
WebFetch
  • Nuxt
  • Auth
  • clerk
  • authentication
  • middleware
  • ssr
  • composables
  • nitro

README badge

README badge for clerk/skills/clerk-nuxt-patterns

Provides Nuxt 3 patterns for Clerk authentication, covering route protection with middleware, server API routes via Nitro, and client-side composables like useAuth and useUser. Includes SSR-safe patterns and organization-aware auth flows using @clerk/nuxt.

Generated from the current SKILL.md.

Does this skill work with Nuxt 3?
Yes. The skill covers Nuxt 3 patterns specifically, including auto-imports, composables, and the Nitro server runtime.
How do I protect routes from unauthenticated users?
Add `definePageMeta({ middleware: 'auth' })` to your page component. The `@clerk/nuxt` module auto-registers the auth middleware.
Can I use useAuth in server API routes?
No. useAuth is client-only. Use `event.context.auth` in Nitro server routes instead, or import `clerkClient` from `@clerk/nuxt/server`.
What causes hydration mismatches with auth state?
Rendering auth state before the component mounts. Fix this by wrapping sensitive content in `<ClientOnly>` or checking `isLoaded` before rendering.
How do I set up environment variables?
Use `NUXT_PUBLIC_CLERK_PUBLISHABLE_KEY` for the public key and `NUXT_CLERK_SECRET_KEY` for the secret key in your `.env` file.

Generated from the current SKILL.md. These answers refresh after source changes.