diff --git a/frontend/lib/api/client.ts b/frontend/lib/api/client.ts index 967e43ca..9b5b7aea 100644 --- a/frontend/lib/api/client.ts +++ b/frontend/lib/api/client.ts @@ -34,7 +34,11 @@ const getApiBaseUrl = (): string => { export const API_BASE_URL = getApiBaseUrl(); // 이미지 URL을 완전한 URL로 변환하는 함수 +// 주의: 모듈 로드 시점이 아닌 런타임에 hostname을 확인해야 SSR 문제 방지 export const getFullImageUrl = (imagePath: string): string => { + // 빈 값 체크 + if (!imagePath) return ""; + // 이미 전체 URL인 경우 그대로 반환 if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) { return imagePath; @@ -42,8 +46,29 @@ export const getFullImageUrl = (imagePath: string): string => { // /uploads로 시작하는 상대 경로인 경우 API 서버 주소 추가 if (imagePath.startsWith("/uploads")) { - const baseUrl = API_BASE_URL.replace("/api", ""); // /api 제거 - return `${baseUrl}${imagePath}`; + // 런타임에 현재 hostname 확인 (SSR 시점이 아닌 클라이언트에서 실행될 때) + if (typeof window !== "undefined") { + const currentHost = window.location.hostname; + + // 프로덕션 환경: v1.vexplor.com → api.vexplor.com + if (currentHost === "v1.vexplor.com") { + return `https://api.vexplor.com${imagePath}`; + } + + // 로컬 개발환경 + if (currentHost === "localhost" || currentHost === "127.0.0.1") { + return `http://localhost:8080${imagePath}`; + } + } + + // SSR 또는 알 수 없는 환경에서는 API_BASE_URL 사용 (fallback) + const baseUrl = API_BASE_URL.replace("/api", ""); + if (baseUrl.startsWith("http://") || baseUrl.startsWith("https://")) { + return `${baseUrl}${imagePath}`; + } + + // 최종 fallback + return imagePath; } return imagePath; diff --git a/frontend/lib/api/file.ts b/frontend/lib/api/file.ts index 4908b381..e6cab8ae 100644 --- a/frontend/lib/api/file.ts +++ b/frontend/lib/api/file.ts @@ -247,10 +247,40 @@ export const getFileDownloadUrl = (fileId: string): string => { /** * 직접 파일 경로 URL 생성 (정적 파일 서빙) + * 주의: 모듈 로드 시점이 아닌 런타임에 hostname을 확인해야 SSR 문제 방지 */ export const getDirectFileUrl = (filePath: string): string => { + // 빈 값 체크 + if (!filePath) return ""; + + // 이미 전체 URL인 경우 그대로 반환 + if (filePath.startsWith("http://") || filePath.startsWith("https://")) { + return filePath; + } + + // 런타임에 현재 hostname 확인 (SSR 시점이 아닌 클라이언트에서 실행될 때) + if (typeof window !== "undefined") { + const currentHost = window.location.hostname; + + // 프로덕션 환경: v1.vexplor.com → api.vexplor.com + if (currentHost === "v1.vexplor.com") { + return `https://api.vexplor.com${filePath}`; + } + + // 로컬 개발환경 + if (currentHost === "localhost" || currentHost === "127.0.0.1") { + return `http://localhost:8080${filePath}`; + } + } + + // SSR 또는 알 수 없는 환경에서는 환경변수 사용 (fallback) const baseUrl = process.env.NEXT_PUBLIC_API_URL?.replace("/api", "") || ""; - return `${baseUrl}${filePath}`; + if (baseUrl.startsWith("http://") || baseUrl.startsWith("https://")) { + return `${baseUrl}${filePath}`; + } + + // 최종 fallback + return filePath; }; /**