feat: add environment configuration files and update API base URL handling for production

This commit is contained in:
JSC
2025-08-09 14:43:09 +02:00
parent b43d29e862
commit d53c08d7a0
10 changed files with 55 additions and 8 deletions

View File

@@ -0,0 +1,2 @@
# Development Environment Variables
VITE_API_BASE_URL=http://localhost:8000

3
.env.production.template Normal file
View File

@@ -0,0 +1,3 @@
# Production Environment Variables
# In production with reverse proxy, we use relative URLs (same origin)
# No API base URL needed - the reverse proxy handles /api routing

View File

@@ -6,6 +6,7 @@
"scripts": {
"dev": "vite --port 8001",
"build": "tsc -b && vite build",
"build:production": "tsc -b && vite build --mode production",
"lint": "eslint .",
"preview": "vite preview"
},

View File

@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'
import { useContext, useEffect, useState } from 'react'
import { ThemeProviderContext, type Theme } from '@/contexts/ThemeContext'
type ThemeProviderProps = {
@@ -49,3 +49,12 @@ export function ThemeProvider({
</ThemeProviderContext.Provider>
)
}
export const useTheme = () => {
const context = useContext(ThemeProviderContext)
if (context === undefined)
throw new Error('useTheme must be used within a ThemeProvider')
return context
}

View File

@@ -26,7 +26,7 @@ import {
ArrowRight,
ArrowRightToLine
} from 'lucide-react'
import { playerService, type PlayerState, type PlayerMode } from '@/lib/api/services/player'
import { playerService, type PlayerState, type PlayerMode, type MessageResponse } from '@/lib/api/services/player'
import { filesService } from '@/lib/api/services/files'
import { playerEvents, PLAYER_EVENTS } from '@/lib/events'
import { toast } from 'sonner'
@@ -79,7 +79,7 @@ export function Player({ className }: PlayerProps) {
}
}, [])
const executeAction = useCallback(async (action: () => Promise<void>, actionName: string) => {
const executeAction = useCallback(async (action: () => Promise<void | MessageResponse>, actionName: string) => {
setIsLoading(true)
try {
await action()

View File

@@ -27,7 +27,12 @@ export function SocketProvider({ children }: SocketProviderProps) {
const createSocket = useCallback(() => {
if (!user) return null
const newSocket = io('http://localhost:8000', {
// Get socket URL - use relative URL in production with reverse proxy
const socketUrl = import.meta.env.PROD
? '' // Use relative URL in production (same origin as frontend)
: (import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000')
const newSocket = io(socketUrl, {
withCredentials: true,
transports: ['polling', 'websocket'],
timeout: 20000,

View File

@@ -12,7 +12,15 @@ export class BaseApiClient implements ApiClient {
}
private buildURL(endpoint: string, params?: Record<string, string | number | boolean | undefined>): string {
const url = new URL(endpoint, this.baseURL)
let url: URL
if (this.baseURL) {
// Full base URL provided
url = new URL(endpoint, this.baseURL)
} else {
// Use relative URL (for reverse proxy)
url = new URL(endpoint, window.location.origin)
}
if (params) {
Object.entries(params).forEach(([key, value]) => {
@@ -22,7 +30,7 @@ export class BaseApiClient implements ApiClient {
})
}
return url.toString()
return this.baseURL ? url.toString() : url.pathname + url.search
}
private async request<T>(

View File

@@ -1,6 +1,19 @@
// API Configuration
const getApiBaseUrl = () => {
// If VITE_API_BASE_URL is explicitly set to empty string, use relative URLs
if (import.meta.env.VITE_API_BASE_URL === '') {
return '' // Use relative URLs (reverse proxy handles routing)
}
// In production with reverse proxy, use relative URL (same origin)
if (import.meta.env.PROD) {
return '' // Use relative URLs in production (reverse proxy handles routing)
}
// Use environment variable in development, fallback to localhost
return import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000'
}
export const API_CONFIG = {
BASE_URL: 'http://localhost:8000',
BASE_URL: getApiBaseUrl(),
TIMEOUT: 30000, // 30 seconds
RETRY_ATTEMPTS: 1,

View File

@@ -1,4 +1,3 @@
import { apiClient } from '../client'
import { API_CONFIG } from '../config'
export class FilesService {

View File

@@ -11,4 +11,11 @@ export default defineConfig({
'@': path.resolve(__dirname, './src'),
},
},
// Production build optimization
build: {
outDir: 'dist',
sourcemap: false, // Disable source maps in production for security
},
// For reverse proxy deployment, ensure assets are served from root
base: '/',
})