devsite/app/utils/strapiImage.ts
2026-04-28 14:10:05 +02:00

70 lines
2.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Sélection d'une variante Strapi (thumbnail / small / medium / large) pour
* limiter le poids transféré sans sacrifier la qualité affichée.
*/
export type StrapiImagePreset = "card" | "thumbnail" | "hero" | "full";
export interface StrapiFormatEntry {
url?: string | null;
width?: number | null;
height?: number | null;
}
export interface StrapiMediaLike {
url?: string | null;
width?: number | null;
height?: number | null;
formats?: {
thumbnail?: StrapiFormatEntry | null;
small?: StrapiFormatEntry | null;
medium?: StrapiFormatEntry | null;
large?: StrapiFormatEntry | null;
} | null;
}
function absUrl(apiUrl: string, path: string | null | undefined): string | null {
if (path == null || path === "") return null;
if (path.startsWith("http://") || path.startsWith("https://")) return path;
return `${apiUrl.replace(/\/$/, "")}${path.startsWith("/") ? "" : "/"}${path}`;
}
/**
* Choisit lURL + dimensions dune image média Strapi selon le contexte daffichage.
* Retourne null si aucune URL exploitable.
*/
export function pickStrapiImage(
apiUrl: string,
media: StrapiMediaLike | null | undefined,
preset: StrapiImagePreset
): { src: string; width: number; height: number } | null {
if (!media?.url) return null;
const f = media.formats;
let chosen: StrapiFormatEntry | undefined;
switch (preset) {
case "thumbnail":
chosen = f?.thumbnail ?? f?.small ?? undefined;
break;
case "card":
chosen = f?.medium ?? f?.small ?? f?.thumbnail ?? undefined;
break;
case "hero":
case "full":
chosen = f?.large ?? f?.medium ?? f?.small ?? undefined;
break;
default:
chosen = f?.medium ?? f?.small;
}
const relPath = chosen?.url ?? media.url;
const src = absUrl(apiUrl, relPath);
if (!src) return null;
const width = Number(chosen?.width ?? media.width) || 800;
const height = Number(chosen?.height ?? media.height) || 600;
return { src, width, height };
}