From harness-claude
Protect routes, redirect unauthenticated users, and transform navigation using Nuxt's layered middleware system for both client and server.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:nuxt-middleware-patternThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Protect routes, redirect unauthenticated users, and transform navigation using Nuxt's layered middleware system
Protect routes, redirect unauthenticated users, and transform navigation using Nuxt's layered middleware system
definePageMetaRoute middleware (client + server navigation guards):
middleware/ — they run during navigation, before the target page component renders.navigateTo to redirect or abortNavigation to cancel:// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
const { isAuthenticated } = useAuth();
if (!isAuthenticated.value) {
return navigateTo('/login');
}
});
definePageMeta:// pages/dashboard.vue
<script setup lang="ts">
definePageMeta({
middleware: 'auth' // single
// middleware: ['auth', 'role-check'] // multiple, runs in order
})
</script>
.global suffix — it runs on every route automatically:// middleware/analytics.global.ts
export default defineNuxtRouteMiddleware((to) => {
trackPageView(to.fullPath);
});
definePageMeta for one-off page guards:definePageMeta({
middleware: [
async function (to, from) {
const allowed = await checkPermission(to.params.id);
if (!allowed) abortNavigation(createError({ statusCode: 403 }));
},
],
});
Server middleware (HTTP-level interception):
server/middleware/ — these run on every incoming HTTP request before any server route:// server/middleware/cors.ts
export default defineEventHandler((event) => {
setHeader(event, 'Access-Control-Allow-Origin', '*');
setHeader(event, 'Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE');
});
event.context to pass data from server middleware to route handlers:// server/middleware/auth.ts
export default defineEventHandler(async (event) => {
const token = getCookie(event, 'auth_token');
if (token) {
event.context.user = await verifyToken(token);
}
});
Auth pattern — combining both layers:
// middleware/auth.ts (client-side guard)
export default defineNuxtRouteMiddleware(() => {
const user = useSupabaseUser();
if (!user.value) return navigateTo('/login');
});
// server/api/protected.get.ts (server-side validation)
export default defineEventHandler((event) => {
if (!event.context.user) throw createError({ statusCode: 401 });
return { secret: 'data' };
});
Nuxt has two distinct middleware layers that serve different purposes:
Route middleware runs in the Vue Router navigation cycle on the client (and during SSR navigation). It has access to the full Nuxt composable context (useNuxtApp, useRuntimeConfig, etc.) and is the right place for UI-level auth checks, redirects, and analytics.
Server middleware runs in Nitro's HTTP pipeline before any route handler. It operates on raw H3 events with no access to Vue reactivity. This is where you handle CORS, rate limiting, auth token validation, and request logging.
Execution order for route middleware:
definePageMeta)SSR vs. CSR behavior:
Route middleware runs on both server (during initial SSR render) and client (on subsequent navigations). Guard against environment-specific APIs:
export default defineNuxtRouteMiddleware(() => {
if (import.meta.server) return; // skip on server
initClientOnlyAnalytics();
});
Redirecting with status codes:
return navigateTo('/new-path', { redirectCode: 301 });
Error handling in middleware:
Throw errors to trigger the Nuxt error page:
throw createError({ statusCode: 403, statusMessage: 'Forbidden' });
When NOT to use:
useAsyncData — middleware is for guards, not loading page datahttps://nuxt.com/docs/guide/directory-structure/middleware
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeRuns code at the edge before a request completes — redirect, rewrite, modify responses, or inject headers. Useful for auth, localization, A/B testing, rate limiting, and security headers.
Route protection and authorization patterns for Clerk middleware. Use when implementing route guards, protecting API routes, configuring middleware matchers, setting up role-based access control, creating auth boundaries, or when user mentions middleware, route protection, auth guards, protected routes, public routes, matcher patterns, or authorization middleware.
Provides Nuxt 3 auth patterns using @clerk/nuxt: middleware, composables, server API routes, and SSR-safe approaches. Good when implementing Clerk authentication in Nuxt apps.