Appearance
Middleware Documentation
Overview
This section documents all route middleware used in the Collage Brand Portal application. Middleware provides route protection, authentication checks, URL validation, and automatic redirects. Middleware files are located in app/middleware/ and run before page components are rendered.
Middleware Architecture
Middleware in Nuxt 4 follows a hierarchical execution model where middleware runs before page components, allowing for route protection, validation, and redirects.
Architecture Pattern
┌─────────────────────────────────────────┐
│ Route Navigation Request │ ← User navigates to route
├─────────────────────────────────────────┤
│ Global Middleware │ ← Runs on ALL routes
│ (auth.global.ts) │
├─────────────────────────────────────────┤
│ Per-Route Middleware │ ← Runs on specific routes
│ (auth.ts, check-url.ts, etc.) │
├─────────────────────────────────────────┤
│ Page Component │ ← Renders if middleware allows
└─────────────────────────────────────────┘Execution Flow
- Global Middleware (
*.global.ts) - Runs first on every navigation - Per-Route Middleware - Runs if specified in
definePageMeta - Page Component - Renders if all middleware passes
Middleware Structure
app/middleware/
├── auth.global.ts # Global authentication middleware (runs on all routes)
├── auth.ts # Per-route authentication middleware
├── check-url.ts # URL validation and brand verification middleware
├── redirect-if-logged-in.ts # Redirect authenticated users from auth pages
├── public-portal-home.ts # Public portal auto-login on home page
├── public-portal-login-redirect.ts # Public portal auto-login on login page
└── public-portal-search.ts # Public portal search page handlingTotal: 7 middleware files
Middleware Types
Global Middleware
Files with .global.ts suffix run automatically on every page navigation. They cannot be disabled and run before any per-route middleware.
Example: auth.global.ts - Runs on all routes to check authentication
Per-Route Middleware
Files without .global.ts suffix run only when explicitly specified in page metadata. They provide optional, page-specific logic.
Usage:
vue
<script setup lang="ts">
definePageMeta({
middleware: 'auth' // Runs auth.ts middleware
})
</script>Middleware Components
Global Authentication Middleware
File: auth.global.ts
Runs on ALL pages automatically. Handles:
- Authentication state validation
- User data fetching if token exists
- Protected route enforcement
- Public route exclusion
Key Features:
- Server-side and client-side execution
- Automatic user data hydration
- Public route detection
- Token-based route support
Per-Route Authentication Middleware
File: auth.ts
Optional authentication check for specific pages. Provides additional authentication validation when needed.
Usage:
vue
definePageMeta({
middleware: 'auth'
})URL Validation Middleware
File: check-url.ts
Comprehensive URL and brand validation middleware. Handles:
- Brand name validation
- Reserved slug detection
- Domain verification
- Brand switching logic
- Anonymous user handling
- Public portal detection
Key Features:
- Brand existence verification
- Domain-based routing
- Session management
- Cookie hydration
- Error handling
Redirect If Logged In Middleware
File: redirect-if-logged-in.ts
Prevents authenticated users from accessing authentication pages. Redirects to dashboard if user is already logged in.
Protected Pages:
- Login
- Forgot password
- Reset password
- Generate password
Public Portal Home Middleware
File: public-portal-home.ts
Handles public portal auto-login on brand home page. Client-only middleware that checks if workspace is a public portal and auto-logs in.
Key Features:
- Client-only execution
- Public portal detection
- Automatic login
- Session validation
Public Portal Login Redirect Middleware
File: public-portal-login-redirect.ts
Auto-logs in public portals when accessing login page. Skips login page for public portals to avoid redirect flash.
Key Features:
- Client-only execution
- Public portal detection
- Automatic redirect to home
- Login page bypass
Public Portal Search Middleware
File: public-portal-search.ts
Guard for unauthenticated visitors on /:brand_name/search. If the workspace is a public portal, auto-login so search results can load; otherwise redirect to login with redirect query preserved.
Key Features:
- Client-only execution
- Public portal detection via usePublicPortal
- Session check before redirect
- Redirect to login with return URL
Middleware Execution Order
1. Global Middleware (auth.global.ts)
- Runs first on every page navigation
- Handles authentication state
- Fetches user data if needed
- Enforces protected routes
2. Per-Route Middleware
- Runs after global middleware
- Executes in order specified in
definePageMeta - Can override or extend global behavior
3. Page Component
- Renders after all middleware passes
- Receives validated route and state
Middleware Patterns
Basic Middleware Structure
typescript
export default defineNuxtRouteMiddleware(async (to, from) => {
// Middleware logic
// Redirect example
return navigateTo('/login')
// Allow navigation (no return or return undefined)
})Authentication Check Pattern
typescript
export default defineNuxtRouteMiddleware(async (to) => {
const authStore = useAuthStore()
if (!authStore.isAuthenticated) {
return navigateTo('/login')
}
})Conditional Redirect Pattern
typescript
export default defineNuxtRouteMiddleware(async (to, from) => {
const authStore = useAuthStore()
if (authStore.isAuthenticated && to.path.includes('/login')) {
return navigateTo('/dashboard')
}
})Public Route Detection Pattern
typescript
export default defineNuxtRouteMiddleware(async (to) => {
const isPublicRoute = to.path.startsWith('/shared-assets') ||
to.path.includes('/login')
if (isPublicRoute) {
return // Allow access
}
// Protected route logic
})Async Operations Pattern
typescript
export default defineNuxtRouteMiddleware(async (to) => {
try {
const result = await someAsyncOperation()
if (!result) {
return navigateTo('/error')
}
} catch (error) {
console.error('Middleware error:', error)
return navigateTo('/error')
}
})Public Routes
Routes that don't require authentication:
/shared-assets/*- Public shared assets*/login- Login page*/forgot-password- Password recovery*/reset-password- Password reset*/generate-password- Password generation*/[token]- Token-based routes
Protected Routes
All other routes require authentication. The global auth middleware automatically:
- Checks authentication state
- Redirects unauthenticated users to login
- Fetches user data if token exists
Middleware Best Practices
- Global vs Per-Route: Use global middleware for app-wide logic (authentication, analytics)
- Performance: Keep middleware lightweight and fast - avoid heavy computations
- Error Handling: Handle errors gracefully with try/catch
- Redirects: Use
navigateTo()for redirects, return the result - Async Operations: Use async/await for async operations
- Store Access: Access stores directly in middleware (they're available)
- SSR Compatibility: Ensure middleware works in both SSR and client contexts
- Avoid Side Effects: Keep middleware focused on navigation logic
- Public Route Detection: Always check for public routes before enforcing auth
- Client-Only Logic: Use
import.meta.clientorimport.meta.serverchecks when needed
Common Use Cases
Route Protection
typescript
// Protect route if not authenticated
if (!authStore.isAuthenticated) {
return navigateTo(`/${brandName}/login`)
}Conditional Access
typescript
// Allow access based on condition
if (user.role !== 'admin') {
return navigateTo('/unauthorized')
}URL Validation
typescript
// Validate URL structure
if (!isValidBrand(brandName)) {
throw createError({
statusCode: 404,
statusMessage: 'Brand not found'
})
}Session Management
typescript
// Hydrate session from cookies
if (import.meta.server) {
const token = useCookie('auth_token')
if (token.value) {
authStore.initialize(token.value)
}
}Related Documentation
- Pages - Pages that use middleware
- Authentication - Authentication system
- Composables - Auth - Auth composables
- Stores - Auth - Auth store