fix: require REACT_APP_API_URL in production, throw clear error if missing
This commit is contained in:
@@ -64,13 +64,21 @@ export const getAuthTokenGetter = (): (() => Promise<string | null>) | null => {
|
||||
|
||||
// Get API URL from environment variables
|
||||
export const getApiUrl = () => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// In production, use the environment variable or fallback
|
||||
return process.env.REACT_APP_API_URL || process.env.REACT_APP_BACKEND_URL;
|
||||
const apiUrl = process.env.REACT_APP_API_URL;
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
// In production, require REACT_APP_API_URL to be set
|
||||
if (isProduction && !apiUrl) {
|
||||
console.error('[apiClient] ❌ REACT_APP_API_URL is not set for production! Please configure in Vercel environment variables.');
|
||||
throw new Error('REACT_APP_API_URL environment variable is required for production. Please set it in your Vercel project settings.');
|
||||
}
|
||||
// In development, prefer the local backend to avoid CORS/proxy header stripping.
|
||||
// If an ngrok URL is set in env but we're on localhost, override to localhost:8000.
|
||||
const envUrl = process.env.REACT_APP_API_URL || process.env.REACT_APP_BACKEND_URL;
|
||||
|
||||
if (isProduction) {
|
||||
return apiUrl;
|
||||
}
|
||||
|
||||
// In development, use localhost by default
|
||||
const envUrl = process.env.REACT_APP_API_URL;
|
||||
const isLocalhost = typeof window !== 'undefined' && window.location.hostname === 'localhost';
|
||||
const isNgrok = envUrl && envUrl.includes('ngrok');
|
||||
if (isLocalhost) {
|
||||
|
||||
@@ -26,7 +26,15 @@ export interface CollectionUpdateRequest {
|
||||
cover_asset_id?: number;
|
||||
}
|
||||
|
||||
const API_BASE_URL = process.env.REACT_APP_API_URL || process.env.REACT_APP_API_BASE_URL || 'http://localhost:8000';
|
||||
const getApiBaseUrl = () => {
|
||||
const url = process.env.REACT_APP_API_URL;
|
||||
if (process.env.NODE_ENV === 'production' && !url) {
|
||||
throw new Error('REACT_APP_API_URL environment variable is required for production');
|
||||
}
|
||||
return url || 'http://localhost:8000';
|
||||
};
|
||||
|
||||
const API_BASE_URL = getApiBaseUrl();
|
||||
|
||||
export const useCollections = () => {
|
||||
const { getToken } = useAuth();
|
||||
|
||||
@@ -49,7 +49,15 @@ export interface AssetListResponse {
|
||||
offset: number;
|
||||
}
|
||||
|
||||
const API_BASE_URL = process.env.REACT_APP_API_URL || process.env.REACT_APP_API_BASE_URL || 'http://localhost:8000';
|
||||
const getApiBaseUrl = () => {
|
||||
const url = process.env.REACT_APP_API_URL;
|
||||
if (process.env.NODE_ENV === 'production' && !url) {
|
||||
throw new Error('REACT_APP_API_URL environment variable is required for production');
|
||||
}
|
||||
return url || 'http://localhost:8000';
|
||||
};
|
||||
|
||||
const API_BASE_URL = getApiBaseUrl();
|
||||
|
||||
export const useContentAssets = (filters: AssetFilters = {}) => {
|
||||
const { getToken } = useAuth();
|
||||
|
||||
@@ -50,8 +50,15 @@ export const useRealTimeData = (options: RealTimeDataOptions) => {
|
||||
|
||||
try {
|
||||
// Build WebSocket URL from environment variables
|
||||
// Consistent with API URL pattern - no hardcoded localhost
|
||||
const apiUrl = process.env.REACT_APP_API_URL || process.env.REACT_APP_BACKEND_URL || '';
|
||||
const getApiBaseUrl = () => {
|
||||
const url = process.env.REACT_APP_API_URL;
|
||||
if (process.env.NODE_ENV === 'production' && !url) {
|
||||
throw new Error('REACT_APP_API_URL environment variable is required for production');
|
||||
}
|
||||
return url || 'http://localhost:8000';
|
||||
};
|
||||
|
||||
const apiUrl = getApiBaseUrl();
|
||||
|
||||
// In development, use proxy (empty string means use same origin)
|
||||
// In production, derive WebSocket URL from API URL
|
||||
|
||||
@@ -77,8 +77,14 @@ class HallucinationDetectorService {
|
||||
private baseUrl: string;
|
||||
|
||||
constructor() {
|
||||
// Consistent API URL pattern - no hardcoded localhost fallback
|
||||
this.baseUrl = process.env.REACT_APP_API_URL || process.env.REACT_APP_BACKEND_URL || '';
|
||||
const getApiBaseUrl = () => {
|
||||
const url = process.env.REACT_APP_API_URL;
|
||||
if (process.env.NODE_ENV === 'production' && !url) {
|
||||
throw new Error('REACT_APP_API_URL environment variable is required for production');
|
||||
}
|
||||
return url || 'http://localhost:8000';
|
||||
};
|
||||
this.baseUrl = getApiBaseUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,8 +12,16 @@ import {
|
||||
CopilotSuggestion
|
||||
} from '../types/seoCopilotTypes';
|
||||
|
||||
// Consistent API URL pattern - use same env vars as other services
|
||||
const API_BASE_URL = process.env.REACT_APP_API_URL || process.env.REACT_APP_BACKEND_URL || '';
|
||||
// API URL - require REACT_APP_API_URL in production
|
||||
const getApiBaseUrl = () => {
|
||||
const url = process.env.REACT_APP_API_URL;
|
||||
if (process.env.NODE_ENV === 'production' && !url) {
|
||||
throw new Error('REACT_APP_API_URL environment variable is required for production');
|
||||
}
|
||||
return url || 'http://localhost:8000';
|
||||
};
|
||||
|
||||
const API_BASE_URL = getApiBaseUrl();
|
||||
|
||||
class SEOApiService {
|
||||
private baseUrl: string;
|
||||
|
||||
@@ -21,8 +21,14 @@ export interface WASuggestResponse {
|
||||
class WritingAssistantService {
|
||||
private baseUrl: string;
|
||||
constructor() {
|
||||
// Consistent API URL pattern - no hardcoded localhost fallback
|
||||
this.baseUrl = process.env.REACT_APP_API_URL || process.env.REACT_APP_BACKEND_URL || '';
|
||||
const getApiBaseUrl = () => {
|
||||
const url = process.env.REACT_APP_API_URL;
|
||||
if (process.env.NODE_ENV === 'production' && !url) {
|
||||
throw new Error('REACT_APP_API_URL environment variable is required for production');
|
||||
}
|
||||
return url || 'http://localhost:8000';
|
||||
};
|
||||
this.baseUrl = getApiBaseUrl();
|
||||
}
|
||||
|
||||
async suggest(text: string): Promise<WASuggestion[]> {
|
||||
|
||||
Reference in New Issue
Block a user