Recipes

Auth Guards and Permissions

Combine route protection, permissions, and expired-session redirects.

Goal

Compose authentication, authorization, and graceful session-expiry behavior with minimal app glue code.

Configure Auth Guards + Unauthorized Redirects

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['better-convex-nuxt'],
  convex: {
    url: process.env.CONVEX_URL,
    auth: {
      enabled: true,
      routeProtection: {
        redirectTo: '/auth/signin',
        preserveReturnTo: true,
      },
      unauthorized: {
        enabled: true,
        redirectTo: '/auth/signin',
        includeQueries: false, // start conservative
      },
    },
    permissions: true,
  },
})

Protect the Page

definePageMeta({
  convexAuth: true,
})

Gate UI by Permission

<script setup lang="ts">
const { can, pending } = usePermissions()
const canEdit = can('post.update')
</script>

<template>
  <button v-if="!pending && canEdit">Edit Post</button>
</template>

What Happens on Expired Session?

  • Mutations/actions that fail with an unauthorized error can trigger a single deduped recovery flow.
  • Local auth state is cleared.
  • The user is redirected to your configured auth route.
  • Query/paginated query-triggered redirects are off by default (includeQueries: false) to avoid noisy background redirects.
  • Set includeQueries: true if you want the same deduped unauthorized recovery flow for queries.