Files
klz-cables.com/lib/imgproxy-loader.ts

72 lines
2.2 KiB
TypeScript

import { getImgproxyUrl } from './imgproxy';
/**
* Next.js Image Loader for imgproxy
*
* @param {Object} props - properties from Next.js Image component
* @param {string} props.src - The source image URL
* @param {number} props.width - The desired image width
* @param {number} props.quality - The desired image quality (ignored for now as imgproxy handles it)
*/
export default function imgproxyLoader({
src,
width,
_quality,
}: {
src: string;
width: number;
_quality?: number;
}) {
// Skip imgproxy for SVGs as they are vectors and don't benefit from resizing,
// and often cause 404s if the source is not correctly resolvable by imgproxy.
if (src.toLowerCase().endsWith('.svg')) {
return src;
}
// Check if src contains custom gravity or aspect ratio query parameters
let gravity = 'sm'; // Use smart gravity (content-aware) by default
let cleanSrc = src;
let calculatedHeight = 0;
let resizingType: 'fit' | 'fill' = 'fit';
try {
// Dummy base needed for relative URLs
const url = new URL(src, 'http://localhost');
const customGravity = url.searchParams.get('gravity');
const aspectRatio = url.searchParams.get('ar'); // e.g. "16:9"
if (customGravity) {
gravity = customGravity;
url.searchParams.delete('gravity');
}
if (aspectRatio) {
const parts = aspectRatio.split(':');
if (parts.length === 2) {
const arW = parseFloat(parts[0]);
const arH = parseFloat(parts[1]);
if (!isNaN(arW) && !isNaN(arH) && arW > 0) {
calculatedHeight = Math.round(width * (arH / arW));
resizingType = 'fill'; // Must use fill to allow imgproxy to crop
}
}
url.searchParams.delete('ar');
}
if (customGravity || aspectRatio) {
cleanSrc = src.startsWith('http') ? url.href : url.pathname + url.search;
}
} catch (e) {
// Fallback if parsing fails
}
// We use the width provided by Next.js for responsive images
// Height is calculated from aspect ratio if provided, otherwise 0 to maintain aspect ratio
return getImgproxyUrl(cleanSrc, {
width,
height: calculatedHeight,
resizing_type: resizingType,
gravity,
});
}