Appearance
API Client Plugin ​
File Information ​
- Path:
app/plugins/api-client.ts - Purpose: Configure API client with authentication, error handling, and account status monitoring
- Type: Universal (runs on both server and client)
- Load Order: 2 (after Pinia, before auth-init)
Overview ​
The API Client plugin creates a configured $fetch instance with automatic authentication token injection, base URL configuration, error handling for 401 responses, and throttled account status monitoring. It provides a global $api instance that can be used throughout the application.
Key Features ​
Automatic Authentication
- Injects auth token from store into requests
- Supports
skipAuthoption to bypass auth - Handles token retrieval safely
Base URL Configuration
- Configures API base URL from runtime config
- Handles internal Nuxt routes (
/api/) separately - Supports external URLs
- Respects
useApiBaseoption
Error Handling
- Handles 401 responses (unauthorized)
- Automatically logs out on 401
- Cleans up abort controllers
Account Status Monitoring
- Throttled account status checks (5 minutes)
- Checks account suspension status
- Auto-redirects suspended accounts to login
Request Cancellation
- Abort controller management
- Cancel all requests function
- Proper cleanup on errors
Code Structure ​
typescript
export default defineNuxtPlugin((nuxtApp) => {
const abortControllers = new Map()
let lastAccountStatusCheck = 0
const ACCOUNT_STATUS_THROTTLE_TIME = 5 * 60 * 1000 // 5 minutes
// Get auth token from store
const getAuthToken = (): string | null => {
try {
const authStore = useAuthStore()
return authStore.accessToken || null
} catch {
return null
}
}
// Throttled account status check
const checkAccountStatusThrottled = async () => {
// Implementation...
}
// Create API client
const apiClient = $fetch.create({
onRequest({ request, options }) {
// Add abort controller
// Configure base URL
// Add auth token
},
async onResponse({ request, response }) {
// Clean up abort controller
// Check account status
},
onResponseError({ request, response }) {
// Clean up abort controller
// Handle 401 errors
}
})
return {
provide: {
api: apiClient,
cancelAllRequests
}
}
})Request Interceptor (onRequest) ​
Abort Controller Management ​
- Creates abort controller for each request
- Stores controller in map for cancellation
- Uses request URL as key
Base URL Configuration ​
- Checks if URL is external (
http://orhttps://) - Skips base URL for internal Nuxt routes (
/api/) - Respects
useApiBaseoption (default: true) - Uses
config.public.apiBaseUrlfor base URL
Authentication Token Injection ​
- Gets token from auth store
- Respects
skipAuthoption - Adds
Authorization: Bearer {token}header - Handles both Headers object and plain object
Response Interceptor (onResponse) ​
Cleanup ​
- Removes abort controller from map
- Prevents memory leaks
Account Status Check ​
- Throttled to once per 5 minutes
- Only runs on successful responses
- Skips for account status check requests
- Checks if account is suspended
- Auto-redirects suspended accounts
Error Interceptor (onResponseError) ​
401 Handling ​
- Detects 401 (Unauthorized) responses
- Automatically logs out user
- Only runs on client-side
- Cleans up abort controller
Account Status Monitoring ​
Throttling ​
- Checks account status at most once per 5 minutes
- Prevents excessive API calls
- Uses timestamp-based throttling
Suspension Handling ​
- Checks
is_suspendedflag in response - Gets brand name from accessible instances
- Logs out user
- Redirects to login page
Request Cancellation ​
cancelAllRequests() ​
Cancels all pending requests.
typescript
const cancelAllRequests = () => {
abortControllers.forEach((controller) => controller.abort())
abortControllers.clear()
}Usage:
typescript
const { $api, cancelAllRequests } = useNuxtApp()
cancelAllRequests() // Cancel all pending requestsUsage Examples ​
Basic API Call ​
typescript
const { $api } = useNuxtApp()
const data = await $api('endpoint', {
method: 'GET'
})Skip Authentication ​
typescript
const { $api } = useNuxtApp()
const data = await $api('public-endpoint', {
method: 'GET',
skipAuth: true
})Skip Base URL ​
typescript
const { $api } = useNuxtApp()
const data = await $api('/api/internal-route', {
method: 'GET',
useApiBase: false
})Options ​
skipAuth ​
- Type:
boolean - Default:
false - Purpose: Skip authentication token injection
useApiBase ​
- Type:
boolean - Default:
true - Purpose: Use API base URL from config
Dependencies ​
- Pinia Plugin - Must load before this plugin (for auth store)
- Runtime Config - Requires
config.public.apiBaseUrl
Security Considerations ​
- Token retrieved from secure store
- 401 errors trigger automatic logout
- Account suspension monitoring
- Request cancellation prevents memory leaks
Notes for Development ​
- Must load before auth-init plugin
- Base URL configuration respects internal routes
- Account status check is throttled to prevent spam
- Abort controllers properly cleaned up
- Error handling is comprehensive
- Supports both Headers object and plain object for headers
Related Documentation ​
- Auth Store - Authentication store
- Auth Init Plugin - Auth initialization
- Account API - Account status API