glam/frontend/src/utils/imageProxy.ts
kempersc 0a38225b36 feat(frontend): Add multi-select filters, URL params, and UI improvements
- Institution Browser: multi-select for types and countries
- URL query param sync for shareable filter URLs
- New utility: countryNames.ts with flag emoji support
- New utility: imageProxy.ts for image URL handling
- New component: SearchableMultiSelect dropdown
- Career timeline CSS and component updates
- Media gallery improvements
- Lazy load error boundary component
- Version check utility
2025-12-15 01:47:11 +01:00

65 lines
2 KiB
TypeScript

/**
* imageProxy.ts
*
* Utility function to proxy external image URLs through the backend
* to avoid hotlinking issues and blocked images.
*
* Many institution websites and image hosts block direct embedding
* (hotlinking) of their images. This utility routes image requests
* through our backend proxy which fetches the image server-side.
*/
/**
* Convert an external image URL to use the backend image proxy.
*
* The proxy endpoint caches images for 1 hour and adds appropriate
* headers to bypass hotlink detection.
*
* @param url - The external image URL to proxy
* @returns Proxied URL via /api/geo/image-proxy, or the original URL if local
*
* @example
* // External image - will be proxied
* proxyImageUrl('https://example.com/logo.png')
* // Returns: '/api/geo/image-proxy?url=https%3A%2F%2Fexample.com%2Flogo.png'
*
* // Local image - returned as-is
* proxyImageUrl('/images/local-logo.png')
* // Returns: '/images/local-logo.png'
*
* // Data URL - returned as-is
* proxyImageUrl('data:image/png;base64,...')
* // Returns: 'data:image/png;base64,...'
*/
export function proxyImageUrl(url: string | undefined | null): string | undefined {
// Return undefined for null/undefined
if (!url) return undefined;
// Don't proxy local URLs (relative paths)
if (url.startsWith('/')) return url;
// Don't proxy data URLs (inline base64 images)
if (url.startsWith('data:')) return url;
// Don't proxy blob URLs
if (url.startsWith('blob:')) return url;
// Proxy all other (external) URLs
return `/api/geo/image-proxy?url=${encodeURIComponent(url)}`;
}
/**
* Check if a URL is an external URL that would benefit from proxying.
*
* @param url - URL to check
* @returns true if external, false if local/data/blob
*/
export function isExternalUrl(url: string | undefined | null): boolean {
if (!url) return false;
if (url.startsWith('/')) return false;
if (url.startsWith('data:')) return false;
if (url.startsWith('blob:')) return false;
return true;
}
export default proxyImageUrl;