releases.shpreview

Nuxt 3 support dropped; createRouteMatcher removed

@clerk/nuxt@3.0.0

2 enhancementsThis release2 enhancementsImprovements to existing featuresAI-tallied from the release notes
From the original release noteView original ↗

Major Changes

  • Drop support for Nuxt 3, which reaches end-of-life on July 31, 2026. @clerk/nuxt now requires Nuxt 4, and the minimum supported Node.js version is now ^20.19.0 || >=22.12.0 to match Nuxt 4's own requirement. If you are still on Nuxt 3, follow the Nuxt upgrade guide to upgrade your project before updating @clerk/nuxt. (#9258) by @wobsoriano

  • Remove createRouteMatcher from @clerk/nuxt/server and the auto-imported client-side createRouteMatcher. Middleware-based auth checks rely on path matching, which can diverge from how requests are actually routed and leave protected resources reachable. Move auth checks into the resources themselves. (#9258) by @wobsoriano

    Protect API routes inside the event handler itself:

    export default defineEventHandler(event => {
      const { isAuthenticated, userId } = event.context.auth();
    
      if (!isAuthenticated) {
        throw createError({ statusCode: 401, statusMessage: 'Unauthorized' });
      }
    
      return { userId };
    });

    Protect pages with a named route middleware and opt pages into it with definePageMeta(). Child routes inherit the middleware applied to their parent, so a single declaration can protect a whole section:

    // app/middleware/auth.ts
    export default defineNuxtRouteMiddleware(() => {
      const { isSignedIn } = useAuth();
    
      if (!isSignedIn.value) {
        return navigateTo('/sign-in');
      }
    });
    <script setup>
    definePageMeta({ middleware: 'auth' });
    </script>

    If you want to hand this work to a coding agent, use this migration prompt:

    Migrate my Nuxt project away from Clerk's removed `createRouteMatcher` API.
    
    1. Find every matcher created with `createRouteMatcher`, along with the logic
       that uses it (throwing 401 errors, calling `navigateTo('/sign-in')`, etc.).
       Matchers can appear in Nitro server middleware (imported from
       `@clerk/nuxt/server`) or in Nuxt route middleware (auto-imported).
    2. For every API route those matchers protected, move the auth check into the
       event handler itself:
       const { isAuthenticated } = event.context.auth();
       if (!isAuthenticated) throw createError({ statusCode: 401, statusMessage: 'Unauthorized' });
       Keep any role or permission checks (`event.context.auth().has(...)`) with
       the resource as well.
    3. For every page those matchers protected, create a named route middleware in
       `app/middleware/` that checks `useAuth()` and redirects with `navigateTo()`,
       then opt pages into it with `definePageMeta({ middleware: 'auth' })`. Child
       routes inherit the middleware applied to their parent.
    4. Remove the `createRouteMatcher` imports and calls. Keep `clerkMiddleware()`
       itself. Middleware logic unrelated to auth protection (headers, locale
       redirects, etc.) may stay, using plain `getRequestURL(event).pathname`
       checks. Plain pathname checks do not normalize percent-encoding
       (`/api/%61dmin` will not match a check for `/api/admin`), so never use
       them for auth or security decisions. Those belong on the resource itself,
       as in steps 2 and 3.
    5. Make sure every route previously covered by a matcher pattern (including
       glob patterns like `/dashboard(.*)`) now has its own check, then verify the
       project builds.

Patch Changes

  • Updated dependencies [2974fb0, 23071bd, e2dd4e2]:
    • @clerk/shared@4.25.9
    • @clerk/backend@3.14.0
    • @clerk/vue@2.4.21

Fetched July 29, 2026

Nuxt 3 support dropped; createRouteMatcher removed… — releases.sh