Files
klz-cables.com/lib/imgproxy.ts
Marc Mintel a60664f964 feat(infra): configure imgproxy to use next.js rewrite proxy
- Added /_img/ rewrite rule in next.config.mjs to proxy image requests to IMGPROXY_URL
- Updated lib/imgproxy.ts to use local /_img path instead of exposed public URL
- Replaced NEXT_PUBLIC_IMGPROXY_URL (build-time) with IMGPROXY_URL (runtime)
- Updated Dockerfile and docker-compose.yml to strip unused build args
2026-02-18 15:57:44 +01:00

81 lines
2.5 KiB
TypeScript

/**
* Generates an imgproxy URL for a given source image and options.
*
* Documentation: https://docs.imgproxy.net/usage/processing
*/
interface ImgproxyOptions {
width?: number;
height?: number;
resizing_type?: 'fit' | 'fill' | 'fill-down' | 'force' | 'auto';
gravity?: string;
enlarge?: boolean;
extension?: string;
}
/**
* Encodes a string to Base64 (URL-safe)
*/
function encodeBase64(str: string): string {
if (typeof Buffer !== 'undefined') {
return Buffer.from(str)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
} else {
// Fallback for browser environment if Buffer is not available
return window.btoa(str).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
}
export function getImgproxyUrl(src: string, options: ImgproxyOptions = {}): string {
// Use local proxy path which is rewritten in next.config.mjs
const baseUrl = '/_img';
// Handle local paths or relative URLs
let absoluteSrc = src;
if (src.startsWith('/')) {
const baseUrlForSrc =
process.env.NEXT_PUBLIC_BASE_URL ||
(typeof window !== 'undefined' ? window.location.origin : 'https://klz-cables.com');
if (baseUrlForSrc) {
absoluteSrc = `${baseUrlForSrc.replace(/\/$/, '')}${src}`;
}
}
// Development mapping: Map local domains to internal Docker hostnames
// so imgproxy can fetch images without SSL issues or external routing
if (process.env.NODE_ENV === 'development') {
if (absoluteSrc.includes('klz.localhost')) {
absoluteSrc = absoluteSrc.replace(/^https?:\/\/klz\.localhost/, 'http://klz-app:3000');
} else if (absoluteSrc.includes('cms.klz.localhost')) {
absoluteSrc = absoluteSrc.replace(/^https?:\/\/cms\.klz\.localhost/, 'http://klz-cms:8055');
}
// Also handle direct container names if needed
}
const {
width = 0,
height = 0,
resizing_type = 'fit',
gravity = 'sm', // Default to smart gravity
enlarge = false,
extension = '',
} = options;
// Processing options
// Format: /rs:<type>:<width>:<height>:<enlarge>/g:<gravity>
const processingOptions = [
`rs:${resizing_type}:${width}:${height}:${enlarge ? 1 : 0}`,
`g:${gravity}`,
].join('/');
// Using /unsafe/ for now as we don't handle signatures yet
// Format: <base_url>/unsafe/<options>/<base64_url>
const suffix = extension ? `@${extension}` : '';
const encodedSrc = encodeBase64(absoluteSrc + suffix);
return `${baseUrl}/unsafe/${processingOptions}/${encodedSrc}`;
}