Skip to content

[Nuxt] SSR useAuth usage #7542

@alimozdemir

Description

@alimozdemir

Preliminary Checks

Reproduction

https://github.com/alimozdemir/clerk-nuxt-ssr

Publishable key

pk_test_ZmxleGlibGUtcmhpbm8tMTQuY2xlcmsuYWNjb3VudHMuZGV2JA

Description

Steps to reproduce:

  1. set auth.global.ts as recommended in nuxt docs (https://clerk.com/docs/guides/secure/protect-pages)
  2. deploy it to cloudflare worker & pages

Expected behavior:

useAuth should support SSR and global middleware should work.

Actual behavior:

It looks like, clerk plugin is not installed at the time of executing the global middleware on ssr.

@clerk/nuxt: useAuth can only be used when the Vue plugin is installed. Learn more: https://clerk.com/docs/reference/vue/clerk-plugin

Image

However, it works ok on the local development environment.

I also have a workaround for the problem, for the server-side we could use the event.context.auth() to check if the user is signedIn.

// Define the routes you want to protect with `createRouteMatcher()`
const isProtectedRoute = createRouteMatcher(['/console(.*)'])

export default defineNuxtRouteMiddleware((to) => {
  if (isProtectedRoute(to)) {
    if (import.meta.server) {
      // On server: use Clerk's server-side auth context
      const event = useRequestEvent();
      const { isAuthenticated } = event?.context.auth();
      if (!isAuthenticated) {
        return navigateTo('/sign-in');  // redirect unauthenticated on SSR
      }
    } else {
      // On client: use reactive state from Clerk's Vue plugin
      const { isSignedIn } = useAuth();
      if (!isSignedIn.value) {
        return navigateTo('/sign-in');
      }
    }
  }
})

Environment

System:
    OS: macOS 15.5
    CPU: (11) arm64 Apple M3 Pro
    Memory: 97.05 MB / 36.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.21.1 - /opt/homebrew/bin/node
    npm: 10.9.4 - /opt/homebrew/bin/npm
    pnpm: 10.20.0 - /opt/homebrew/bin/pnpm
    bun: 1.1.13 - /opt/homebrew/bin/bun
  Browsers:
    Chrome: 143.0.7499.170
    Edge: 143.0.3650.96
    Safari: 18.5
  npmPackages:
    @clerk/nuxt: ^1.13.10 => 1.13.10 
    @clerk/themes: ^2.4.46 => 2.4.46 
    @iconify-json/ph: ^1.2.2 => 1.2.2 
    @inspira-ui/plugins: ^0.0.1 => 0.0.1 
    @internationalized/date: ^3.10.0 => 3.10.0 
    @nuxt/fonts: 0.12.1 => 0.12.1 
    @radix-ui/colors: ^3.0.0 => 3.0.0 
    @tailwindcss/vite: ^4.1.17 => 4.1.17 
    @types/d3: ^7.4.3 => 7.4.3 
    @types/topojson-client: ^3.1.5 => 3.1.5 
    @vee-validate/zod: ^4.15.1 => 4.15.1 
    @vueuse/core: ^14.1.0 => 14.1.0 
    class-variance-authority: ^0.7.1 => 0.7.1 
    clsx: ^2.1.1 => 2.1.1 
    cobe: ^0.6.5 => 0.6.5 
    d3: ^7.9.0 => 7.9.0 
    dayjs: ^1.11.19 => 1.11.19 
    jsvectormap: ^1.7.0 => 1.7.0 
    lucide-vue-next: ^0.553.0 => 0.553.0 
    motion-v: 1.7.4 => 1.7.4 
    nuxt: ^4.2.2 => 4.2.2 
    nuxt-echarts: ^1.0.1 => 1.0.1 
    odata-query: ^8.0.7 => 8.0.7 
    reka-ui: ^2.7.0 => 2.7.0 
    shadcn-nuxt: 2.4.3 => 2.4.3 
    tailwind-merge: ^3.3.1 => 3.3.1 
    tailwindcss: ^4.1.17 => 4.1.17 
    topojson-client: ^3.1.0 => 3.1.0 
    tw-animate-css: ^1.4.0 => 1.4.0 
    typescript: ^5.9.3 => 5.9.3 
    unplugin-icons: ^22.5.0 => 22.5.0 
    unplugin-vue-components: ^30.0.0 => 30.0.0 
    vaul-vue: ^0.4.1 => 0.4.1 
    vee-validate: ^4.15.1 => 4.15.1 
    vue: latest => 3.5.24 
    vue-router: latest => 4.6.3 
    zod: ^4.1.12 => 4.1.12

Metadata

Metadata

Assignees

Labels

needs-triageA ticket that needs to be triaged by a team member

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions