Protect content from unauthenticated users
This guide demonstrates how to protect content from unauthenticated users in your Nuxt application.
Protect a single page
The useAuth() composable provides access to the current user's authentication state. It includes the isSignedIn property to check if the active user is signed in, which is helpful for protecting a page.
<script setup>
const { isSignedIn, isLoaded, userId } = useAuth()
</script>
<template>
<!-- Use `isLoaded` to check if Clerk is loaded -->
<div v-if="!isLoaded">Loading...</div>
<!-- Use `isSignedIn` to check if the user is signed in -->
<div v-else-if="!isSignedIn">Sign in to access this page</div>
<!-- Use `userId` to access the current user's ID -->
<div v-else>Hello, {{ userId }}!</div>
</template>Protect multiple pages
To protect groups of pages, use Nuxt's built-in route middleware instead of matching paths yourself. This keeps the page structure as the source of truth, so there's no separate list of paths that can fall out of sync with your routes.
Named middleware
Create a named middleware that checks the user's authentication status, then opt pages into it with definePageMeta(). Child routes inherit the middleware applied to their parent, so a single declaration can protect a whole section.
export default defineNuxtRouteMiddleware(() => {
// Use the `useAuth()` composable to access the `isSignedIn` property
const { isSignedIn } = useAuth()
// Redirect the user to the sign-in page if they aren't signed in
if (!isSignedIn.value) {
return navigateTo('/sign-in')
}
})<script setup lang="ts">
definePageMeta({ middleware: 'auth' })
</script>
<template>
<NuxtPage />
</template>Route groups
If you're on Nuxt 4.3 or later, you can group pages with route groups (a folder wrapped in parentheses) and protect them in a single global middleware. Each route exposes the groups it belongs to on to.meta.groups.
pages/
(public)/
sign-in.vue
pricing.vue
(protected)/
dashboard.vue
settings.vueexport default defineNuxtRouteMiddleware((to) => {
// Only guard pages in the `protected` route group
if (!to.meta.groups?.includes('protected')) return
const { isSignedIn } = useAuth()
if (!isSignedIn.value) {
return navigateTo('/sign-in')
}
})Feedback
Last updated on