Skip to content

[FE-01] Set up axios API client with JWT auth interceptor and silent token refresh on 401 #813

Description

@mftee

Overview

The frontend is a blank placeholder (<div>HomePage</div>). Before any UI can be built, an API client layer must exist so components can make authenticated requests to the NestJS backend. Without a shared client, every component would duplicate auth header logic, and silent token refresh would need to be reimplemented everywhere.

Background

The NestJS backend runs at http://localhost:6004 (configurable via NEXT_PUBLIC_API_URL env var). The backend uses JWT access tokens (short-lived) and refresh tokens (stored as an httpOnly cookie or returned in the response body).

Files to create:

  • frontend/lib/api.ts — axios instance with base URL and interceptors

Client setup:

  1. Base URL from NEXT_PUBLIC_API_URL env
  2. Request interceptor: attach access token from Zustand store (or localStorage) as Authorization: Bearer {token} header
  3. Response interceptor: on 401, call POST /api/auth/refresh to get a new access token, then retry the original request once
  4. On refresh failure (401 again), call logout() from the Zustand auth store and redirect to /login

Acceptance Criteria

  • Axios instance created and exported from frontend/lib/api.ts
  • Base URL read from NEXT_PUBLIC_API_URL environment variable
  • All requests include the Authorization header when a token is present
  • 401 responses trigger a silent token refresh before retrying the request
  • If refresh fails, user is logged out and redirected to /login
  • Non-401 errors are passed through without retry

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions