From harness-claude
Implements Nuxt middleware patterns to protect routes, redirect unauthenticated users, run navigation logic, and intercept server requests for auth and logging.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Protect routes, redirect unauthenticated users, and transform navigation using Nuxt's layered middleware system
Implements Next.js middleware to run edge code before requests complete for route protection, redirects, rewrites, header injection, and rate limiting.
Implements Clerk authentication patterns in Nuxt 3 using @clerk/nuxt: middleware for route protection, composables (useAuth/useUser), server API routes, and SSR handling. Triggers on Nuxt auth queries.
Implements Next.js 15/16 middleware for Edge (middleware.ts) and Node.js (proxy.ts), handling authentication, RBAC, redirects, rewrites, i18n, security headers, rate limiting, matchers, and geo routing.
Share bugs, ideas, or general feedback.
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