API Communication
How the frontend communicates with the backend API
API Communication
Overview
The frontend communicates with the backend exclusively through REST API calls. All requests go through the useApi composable, which handles authentication headers and token refresh automatically.
The useApi Composable
const api = useApi()
// GET request (authenticated)
const profile = await api('/api/v1/user/profile')
// POST request
const result = await api('/api/v1/auth/login', {
method: 'POST',
body: { email, password }
})
What It Does
- Base URL injection — Prepends
NUXT_PUBLIC_API_BASE_URLto all requests - Auth headers — Automatically adds
Authorization: Bearer <token>when a token exists - 401 retry — On a 401 response, attempts to refresh the token and retry the request once
- Logout on failure — If the refresh fails, clears the auth store (logs the user out)
Request Flow
Frontend Request
│
├── Add Authorization header (if token exists)
│
▼
Backend API
│
├── 200/201 → Return data
│
├── 401 → Refresh token
│ │
│ ├── Success → Retry original request
│ │
│ └── Failure → Logout user
│
└── Other error → Return error to caller
API Endpoints Used
| Frontend Feature | Backend Endpoint | Method |
|---|---|---|
| Register | /api/v1/auth/register | POST |
| Login | /api/v1/auth/login | POST |
| Social Login | /api/v1/auth/social | POST |
| Logout | /api/v1/auth/logout | POST |
| Token Refresh | /api/v1/auth/token/refresh | POST |
| Forgot Password | /api/v1/auth/forgot-password | POST |
| Reset Password | /api/v1/auth/reset-password | POST |
| User Profile | /api/v1/user/profile | GET |
| Change Password | /api/v1/user/change-password | POST |
| Pricing Plans | /api/v1/plans | GET |
| Checkout Session | /api/v1/subscription/checkout | POST |
| Subscription Status | /api/v1/subscription | GET |
CORS Configuration
The backend must allow requests from the frontend origin. Set CORS_ALLOW_ORIGIN in the backend's .env.local:
# Local development
CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$
# Production
CORS_ALLOW_ORIGIN=^https://yourdomain\.com$
Error Handling
Each composable handles API errors with a consistent pattern:
const { error, isLoading } = useAuth()
// error is a Ref<string | null>
// isLoading is a Ref<boolean>
Errors from the backend are parsed from the response JSON ({ "error": "message" }) and exposed as reactive refs that components can display.