Skip to content

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 ​

  1. Automatic Authentication

    • Injects auth token from store into requests
    • Supports skipAuth option to bypass auth
    • Handles token retrieval safely
  2. Base URL Configuration

    • Configures API base URL from runtime config
    • Handles internal Nuxt routes (/api/) separately
    • Supports external URLs
    • Respects useApiBase option
  3. Error Handling

    • Handles 401 responses (unauthorized)
    • Automatically logs out on 401
    • Cleans up abort controllers
  4. Account Status Monitoring

    • Throttled account status checks (5 minutes)
    • Checks account suspension status
    • Auto-redirects suspended accounts to login
  5. 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:// or https://)
  • Skips base URL for internal Nuxt routes (/api/)
  • Respects useApiBase option (default: true)
  • Uses config.public.apiBaseUrl for base URL

Authentication Token Injection ​

  • Gets token from auth store
  • Respects skipAuth option
  • 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_suspended flag 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 requests

Usage 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