Cursor Agent
Deploy viewer for DynamicIntelligence/humanoid-robots-training-dataset
39d06f7
/**
* Helper functions for API calls
* Handles both server-side and client-side URL construction
*
* IMPORTANT: We cannot import 'next/headers' at top level because it breaks client-side usage.
* We use dynamic import only when needed on server-side.
*/
/**
* Get the base URL for API calls
* For server-side, we need absolute URLs
* For client-side, we can use relative URLs
*/
export async function getApiBaseUrl(): Promise<string> {
// Server-side: need absolute URL
if (typeof window === 'undefined') {
try {
// Dynamically import headers only when server-side (avoids client-side import error)
const { headers } = await import('next/headers');
const headersList = await headers();
const host = headersList.get('host');
const protocol = headersList.get('x-forwarded-proto') || 'https';
if (host) {
return `${protocol}://${host}`;
}
} catch (error) {
// headers() might not be available in all contexts (e.g., during build)
// Fall through to environment variables
}
// Fallback: try environment variables
const spaceUrl =
process.env.SPACE_URL ||
process.env.NEXT_PUBLIC_APP_URL ||
process.env.VERCEL_URL ||
process.env.HF_SPACE_URL;
if (spaceUrl) {
// Ensure it has protocol
if (spaceUrl.startsWith('http://') || spaceUrl.startsWith('https://')) {
// Remove trailing slash
return spaceUrl.endsWith('/') ? spaceUrl.slice(0, -1) : spaceUrl;
}
return `https://${spaceUrl}`;
}
// Last resort: use relative URL (Next.js should handle this for same-origin)
return '';
}
// Client-side: use relative URL (empty string)
return '';
}
/**
* Build proxy URL for Hugging Face requests
* Automatically handles server-side vs client-side
* Note: This is async because getApiBaseUrl() is async (needed for server-side)
*/
export async function buildProxyUrl(targetUrl: string): Promise<string> {
const apiBase = await getApiBaseUrl();
const encodedUrl = encodeURIComponent(targetUrl);
return `${apiBase}/api/hf-proxy?url=${encodedUrl}`;
}