Make API URL dynamic based on hostname
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
- localhost/127.0.0.1 → http://localhost:8000/api/v1 - Local network IPs → http://{hostname}:8000/api/v1 - Production domains → https://{hostname}/api/v1 (requires reverse proxy)
This commit is contained in:
@ -1,20 +1,44 @@
|
|||||||
/**
|
/**
|
||||||
* API client for pounce backend
|
* API client for pounce backend
|
||||||
|
*
|
||||||
|
* API URL is determined dynamically based on the current hostname:
|
||||||
|
* - localhost/127.0.0.1 → http://localhost:8000/api/v1
|
||||||
|
* - Local network IPs (10.x, 192.168.x) → http://{hostname}:8000/api/v1
|
||||||
|
* - Production (any other domain) → https://{hostname}/api/v1 (requires reverse proxy)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Ensure API_BASE ends with /api/v1 and no trailing slash
|
const getApiBase = (): string => {
|
||||||
const getApiBase = () => {
|
// Server-side rendering: use environment variable or localhost
|
||||||
const baseUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'
|
if (typeof window === 'undefined') {
|
||||||
// Remove trailing slash if present
|
const baseUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000/api/v1'
|
||||||
const cleanBase = baseUrl.replace(/\/$/, '')
|
return baseUrl.replace(/\/$/, '')
|
||||||
// Add /api/v1 if not present
|
|
||||||
if (cleanBase.endsWith('/api/v1')) {
|
|
||||||
return cleanBase
|
|
||||||
}
|
}
|
||||||
return `${cleanBase}/api/v1`
|
|
||||||
|
const { protocol, hostname, port } = window.location
|
||||||
|
|
||||||
|
// Localhost development
|
||||||
|
if (hostname === 'localhost' || hostname === '127.0.0.1') {
|
||||||
|
return 'http://localhost:8000/api/v1'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local network (10.x.x.x, 192.168.x.x, 172.16-31.x.x)
|
||||||
|
if (/^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)/.test(hostname)) {
|
||||||
|
return `http://${hostname}:8000/api/v1`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Production: use same protocol and domain with /api/v1 path
|
||||||
|
// This requires a reverse proxy (nginx/caddy) to route /api/v1 to the backend
|
||||||
|
return `${protocol}//${hostname}/api/v1`
|
||||||
}
|
}
|
||||||
|
|
||||||
const API_BASE = getApiBase()
|
// Lazy-evaluated to ensure window is available on client
|
||||||
|
let _apiBase: string | null = null
|
||||||
|
const getApiBaseUrl = (): string => {
|
||||||
|
if (_apiBase === null) {
|
||||||
|
_apiBase = getApiBase()
|
||||||
|
}
|
||||||
|
return _apiBase
|
||||||
|
}
|
||||||
|
|
||||||
interface ApiError {
|
interface ApiError {
|
||||||
detail: string
|
detail: string
|
||||||
@ -44,7 +68,7 @@ class ApiClient {
|
|||||||
endpoint: string,
|
endpoint: string,
|
||||||
options: RequestInit = {}
|
options: RequestInit = {}
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const url = `${API_BASE}${endpoint}`
|
const url = `${getApiBaseUrl()}${endpoint}`
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...options.headers as Record<string, string>,
|
...options.headers as Record<string, string>,
|
||||||
|
|||||||
Reference in New Issue
Block a user