Token Types
Define type-safe custom JWT token payloads for your application.
Understanding Token Claims
Nuxt Aegis uses two key types for JWT tokens:
BaseTokenClaims - The Foundation
Standard JWT claims that are always present in every token:
sub- User ID (subject)email,name,picture- User profile fieldsiss,aud,iat,exp- JWT metadata fieldsprovider- Authentication provider nameimpersonation- Impersonation context (if active)
CustomTokenClaims<T> - Your Application Type
Combines BaseTokenClaims with your application-specific claims:
typescript
// BaseTokenClaims: sub, email, name, iss, exp, etc.
// +
// Your custom claims: role, permissions, etc.
// =
// CustomTokenClaims<T>: Everything togetherThis naming makes the relationship clear: you're adding custom claims on top of the base claims.
CustomTokenClaims Helper
The CustomTokenClaims<T> helper type combines BaseTokenClaims with your custom claims while ensuring type safety and JSON-serializability.
typescript
import type { CustomTokenClaims } from '#nuxt-aegis'
type AppTokenClaims = CustomTokenClaims<{
role: string // Your custom claim
permissions: string[] // Your custom claim
organizationId: string // Your custom claim
}>
// AppTokenClaims now includes:
// - Base claims: sub, email, name, iss, exp, provider...
// - Custom claims: role, permissions, organizationIdSupported Value Types
Custom claims must be JSON-serializable:
- Primitives:
string,number,boolean,null,undefined - Arrays:
string[],number[] - Objects (one level):
{ [key: string]: string | number | boolean | ... }
typescript
type AppTokenClaims = CustomTokenClaims<{
// ✓ Primitives
role: string
isActive: boolean
loginCount: number
// ✓ Arrays
permissions: string[]
favoriteNumbers: number[]
// ✓ Nested objects (one level)
metadata: {
tenantId: string
plan: string
}
// ✗ NOT ALLOWED
// callback: () => void // Functions not allowed
// nested: { deep: { value: string } } // Deep nesting not allowed
}>Client-Side Usage
Use the generic type parameter with useAuth():
typescript
import type { AppTokenClaims } from '~/types/token'
const { user, login, logout } = useAuth<AppTokenClaims>()
// All fields are fully typed
if (user.value) {
console.log(user.value.sub) // Standard field
console.log(user.value.role) // Custom claim - fully typed!
console.log(user.value.permissions) // string[] - fully typed!
}ExtractClaims Utility
Extract only custom claims from a token payload:
typescript
import type { ExtractClaims } from '#nuxt-aegis'
type AppTokenClaims = CustomTokenClaims<{
role: string
permissions: string[]
}>
type OnlyCustomClaims = ExtractClaims<AppTokenClaims>
// Result: { role: string, permissions: string[] }Useful for:
- Type composition
- Claim validation functions
- Documenting which fields are custom
Best Practices
✓ Do
typescript
// Keep payloads small and focused
type AppTokenClaims = CustomTokenClaims<{
role: 'admin' | 'user' | 'guest' // Use literal types for enums
permissions: string[]
tenantId: string
}>
// Use meaningful field names
type AppTokenClaims = CustomTokenClaims<{
organizationId: string // ✓ Clear
orgId: string // ✗ Ambiguous
}>✗ Don't
typescript
// DON'T include sensitive data
type BadTokenPayload = CustomTokenClaims<{
password: string // ✗ Never!
hashedPassword: string // ✗ Never!
apiKey: string // ✗ Never!
secret: string // ✗ Never!
}>
// DON'T include large data
type BadTokenPayload = CustomTokenClaims<{
profileImageBase64: string // ✗ Use URLs instead
fullDocument: object // ✗ Use references
}>Token Size Warning
Nuxt Aegis automatically warns in development if your token payload exceeds 1KB:
Token payload size (1234 bytes) exceeds recommended threshold (1024 bytes).
Consider reducing the payload size by removing unnecessary claims or using
references instead of large values.Keep tokens small for:
- Better performance
- Lower bandwidth usage
- Compatibility with all systems
Complete Example
typescript
// ~/types/token.ts
import type { CustomTokenClaims } from '#nuxt-aegis'
/**
* Application JWT token payload
*
* @example
* ```typescript
* const { user } = useAuth<AppTokenClaims>()
* if (user.value?.role === 'admin') {
* // Admin-specific logic
* }
* ```
*/
export type AppTokenClaims = CustomTokenClaims<{
/** User role in the system */
role: 'admin' | 'user' | 'guest'
/** Array of permission strings */
permissions: string[]
/** Organization/tenant ID */
organizationId: string
/** Optional: Additional metadata */
metadata?: {
department?: string
region?: string
}
}>Next Steps
- Database Types - Separate DB models from JWT payloads
- Server Types - Use types in server handlers
- API Reference - Complete type documentation