-
Notifications
You must be signed in to change notification settings - Fork 421
Description
Preliminary Checks
-
I have reviewed the documentation: https://clerk.com/docs
-
I have searched for existing issues: https://github.com/clerk/javascript/issues
-
I have not already reached out to Clerk support via email or Discord (if you have, no need to open an issue here)
-
This issue is not a question, general help request, or anything other than a bug report directly related to Clerk. Please ask questions in our Discord community: https://clerk.com/discord.
Reproduction
https://github.com/alimozdemir/clerk-nuxt-ssr
Publishable key
pk_test_ZmxleGlibGUtcmhpbm8tMTQuY2xlcmsuYWNjb3VudHMuZGV2JA
Description
Steps to reproduce:
- set auth.global.ts as recommended in nuxt docs (https://clerk.com/docs/guides/secure/protect-pages)
- 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
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