sidebar_position: 1 title: Environment and API client description: Environment variables, shared Axios client behavior, auth flow, and API integration rules for the Academia frontend.
Environment and API client
The Academia UI is a frontend that depends on a deployed API. The current Next.js app uses environment variables, a shared Axios client, tenant-aware headers, and a few same-origin proxy routes to keep integration behavior consistent.
Fastest route through this guide
- Start with Required environment variables if you are setting up a local or deployed frontend.
- Read How the shared API client behaves if you need the exact request and response rules.
- Jump to Auth and tenant context if login or tenant routing is the main concern.
- Use Practical endpoint families when you are looking for the main backend areas the UI already calls.
Required environment variables
The frontend README currently describes these environment variables as the main integration surface:
NEXT_PUBLIC_API_BASE_URL="https://api.academia.et/api/v1"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
NEXT_PUBLIC_ACADEMIA_MOCK_ROLE="coordinator"
NEXT_PUBLIC_API_BASE_URL
This is the most important one. The shared Axios client expects the value to already include /api/v1.
Examples:
NEXT_PUBLIC_API_BASE_URL="http://localhost:3001/api/v1"
NEXT_PUBLIC_API_BASE_URL="https://api.academia.et/api/v1"
Because /api/v1 is already included, frontend API modules call routes such as /auth/login, /tenant/current, or /project-groups/me without repeating the version prefix.
NEXT_PUBLIC_APP_URL
This is useful for local app URL awareness and deployment-level integration, especially when frontend-generated links or route-aware features need a stable app origin.
NEXT_PUBLIC_ACADEMIA_MOCK_ROLE
This is optional and mainly helpful for local UI previews. The README lists role values such as:
department_headcoordinatoradvisorevaluatorstudentdepartment_committee
Use it only for preview or isolated UI work. Real workflow verification should still happen against authenticated backend data.
How the shared API client behaves
The frontend centralizes backend communication in src/lib/api/client.ts in the upstream Academia repository.
Base URL and defaults
The client currently:
- uses
NEXT_PUBLIC_API_BASE_URLas the AxiosbaseURL - falls back to
http://localhost:3001/api/v1when the env var is missing - sets
Content-Type: application/jsonby default - enables
withCredentials: true
This means local development can still work with the default backend port, but production or multi-environment deployments should set the env var explicitly.
Request interceptor rules
On the browser side, the request interceptor reads auth state and adds the headers the backend expects.
Current behavior includes:
Authorization: Bearer <accessToken>when a token existsX-Tenant-Domain: <tenantDomain>when tenant context exists- fallback lookup of
tenantDomainfrom persistedauth-storagein local storage if the in-memory store is empty
This is why feature-specific API modules stay simple. They call apiClient.get(...) or apiClient.post(...), and the shared client injects auth and tenant context automatically.
Response interceptor rules
The response interceptor also normalizes backend responses.
Current behavior includes:
- unwrapping the backend success envelope from
{ success, message, data, timestamp }intoresponse.data - flattening backend error envelopes into a clear
error.message - converting throttling and
429behavior into the normalized messageToo many requests. Try again later. - treating
401as a dead session only for selected identity-sensitive routes instead of logging users out on every unauthorized response
That last rule matters because the frontend intentionally avoids random logout behavior when a partially wired feature returns 401.
Auth and tenant context
The current auth store is more than a token holder. It also preserves tenant routing context and canonical user information.
Login flow
The frontend login flow posts to:
POST /auth/login
with a payload that may include:
{
"email": "depthead@university.edu",
"password": "YourPassword",
"tenantDomain": "addisababauniversity6"
}
The auth store currently:
- includes
tenantDomainfrom the form or the previously stored auth state - stores
accessToken,refreshToken,user, andtenantDomainafter login - follows login with
/auth/meas a best-effort canonical refresh of the current user profile
Session profile shape
The backend GET /auth/me response already includes tenant-aware user data such as:
tenantIdtenantDomaintenantobject withid,name,domain, andstatusdepartmentIdand department informationroles- optional
tenantVerificationstate for department-head-first flows
This matters because both dashboard routing and tenant-aware API behavior depend on the current user carrying the right tenant context.
Same-origin proxy routes in Next.js
The frontend does not send every request directly to the backend. A few public or cross-origin-sensitive flows are proxied through Next.js route handlers.
Current examples in the frontend repo include:
/api/invitations/accept/preview/api/invitations/accept/api/contact
These handlers use NEXT_PUBLIC_API_BASE_URL server-side, forward JSON payloads upstream, and return the upstream status and payload back to the client.
This pattern is useful when:
- the flow is public and should avoid browser-side CORS issues
- the frontend wants a stable same-origin route for form submission
- you need server-side control of request forwarding without exposing more client complexity
Realtime and derived origins
Not every integration goes through REST alone. The current frontend also derives a socket origin from NEXT_PUBLIC_API_BASE_URL for realtime features.
Current examples include:
- notifications socket integration
- chat socket integration
The socket helpers derive the origin from the API base URL and authenticate using:
accessTokentenantDomain
This keeps realtime features aligned with the same auth and tenant context used by the Axios client.
Practical endpoint families
The UI already spans several backend areas. These are the main families contributors should recognize first.
Auth and identity
POST /auth/loginGET /auth/meGET /auth/profile
Tenant and department management
GET /tenant/currentPATCH /tenant/addressPOST /tenant/verification/documentGET /tenant/usersGET /tenant/users/pagedPUT /tenant/users/:idDELETE /tenant/users/:idPATCH /tenant/users/:id/reactivateGET /tenant/invitationsPOST /tenant/invitationsPOST /tenant/invitations/:id/resend
Student group formation
POST /group-leader-requestsGET /group-leader-requests/mePOST /project-groupsGET /project-groups/mePOST /project-groups/:groupId/join-requestsPOST /project-groups/me/submitGET /project-groups/review/submittedPOST /project-groups/review/:groupId/approvePOST /project-groups/review/:groupId/reject
Proposal and project work
POST /projects/proposalsPOST /projects/proposals/with-proposal-pdfGET /projects/proposals/groupPUT /projects/proposals/:id/statusPUT /projects/proposals/:id/advisorGET /projectsGET /projects/:id
Milestones and advisor review
GET /projects/advisors/meGET /projects/advisors/me/projectsGET /projects/advisors/me/milestone-review-queueGET /projects/milestones/:id/submissionsPUT /projects/milestones/:id/submissions/:submissionId/approve
Notifications and push
GET /notifications/push/vapid-public-key- push subscription endpoints under
/notifications/push - proposal and group-review notifications emitted by backend services
Integration rules contributors should keep consistent
- Keep
NEXT_PUBLIC_API_BASE_URLversioned with/api/v1; do not duplicate the prefix in feature modules. - Use the shared Axios client instead of ad hoc
fetchfor authenticated app routes so auth and tenant headers are injected consistently. - Use same-origin Next.js proxy handlers when a public flow would otherwise create browser-side CORS or token-handling problems.
- Document endpoint families and behavior, not secrets or real tokens.
- Treat tenant context as part of every request model, not as an optional afterthought.
Best next reads
- Open Auth, session, and tenant bootstrap if you want the full login-to-dashboard integration path.
- Open Multi-tenancy if you want the host, middleware, and tenant-isolation side of the integration model.
- Open Backend modules, realtime, and notifications if you want the main service families behind chat, push, and workflow events.
- Open Local development if you are preparing a local frontend-backend setup.
- Open Architecture if you want the broader product-layer view before going deeper into code integration.
:::note Security Never commit real tokens or production secrets. Document variable names, allowed values, and purpose. Keep real credentials in local env files, deployment settings, or secret stores. :::