diff --git a/web/lib/api.ts b/web/lib/api.ts index 88bb940..e8b57f2 100644 --- a/web/lib/api.ts +++ b/web/lib/api.ts @@ -1,8 +1,31 @@ // Backend API client. -// NEXT_PUBLIC_API_BASE 는 docker-compose 에서 http://localhost:8000 으로 주입됨. +// +// API 베이스 해석 우선순위: +// 1) NEXT_PUBLIC_API_BASE 가 localhost/127.0.0.1 이 아닌 명시값 → 그대로 사용 +// (예: 프로덕션 https://api.example.com) +// 2) 브라우저 환경 → window.location.hostname:8000 (LAN 접속도 자동 대응) +// 3) SSR 폴백 → http://localhost:8000 +// +// docker-compose 가 NEXT_PUBLIC_API_BASE=http://localhost:8000 을 주입하는 경우가 흔한데, +// LAN 의 다른 PC 에서 http://:3000 으로 접속하면 inline 된 localhost 가 그쪽 PC 의 +// localhost 를 가리켜 깨진다. 그래서 localhost/127.0.0.1 값은 신뢰하지 않고 페이지 host 로 +// 폴백. -const RAW_BASE = process.env.NEXT_PUBLIC_API_BASE ?? "http://localhost:8000"; -export const API_BASE = RAW_BASE.replace(/\/$/, ""); +function resolveApiBase(): string { + const raw = process.env.NEXT_PUBLIC_API_BASE; + const env = raw && raw.length > 0 ? raw.replace(/\/$/, "") : ""; + const envIsLocal = !env || /\/\/(localhost|127\.0\.0\.1)(?::|$)/.test(env); + if (typeof window !== "undefined") { + if (envIsLocal) { + return `${window.location.protocol}//${window.location.hostname}:8000`; + } + return env; + } + // SSR + return env || "http://localhost:8000"; +} + +export const API_BASE = resolveApiBase(); export type Symbol = { code: string;