44 lines
1.9 KiB
JavaScript
44 lines
1.9 KiB
JavaScript
/**
|
||
* Field validation for the favicon upload: Google rejects favicons under 48×48,
|
||
* so warn the editor at save time if the uploaded icon is too small or not
|
||
* square. This ENFORCES the requirement instead of silently shipping a favicon
|
||
* Google won't display.
|
||
*
|
||
* Attach to the favicon field's validate (or as a beforeValidate hook on the
|
||
* Media relationship). Non-blocking by default — returns a warning string that
|
||
* Payload surfaces; make it throw if you want a hard block.
|
||
*
|
||
* Note: dimensions come from the related Media doc (Payload stores width/height
|
||
* for image uploads), so this checks the resolved upload, not the raw file.
|
||
*/ export const validateFaviconField = async ({ req, value })=>{
|
||
if (!value) {
|
||
return value;
|
||
} // no favicon set → nothing to validate (optional field)
|
||
try {
|
||
const media = await req.payload.findByID({
|
||
id: typeof value === 'object' ? value.id : value,
|
||
collection: 'media',
|
||
depth: 0
|
||
});
|
||
const width = media.width;
|
||
const height = media.height;
|
||
const mimeType = media.mimeType;
|
||
// SVG scales infinitely — skip size checks.
|
||
if (mimeType === 'image/svg+xml') {
|
||
return value;
|
||
}
|
||
if (typeof width === 'number' && typeof height === 'number') {
|
||
if (width < 48 || height < 48) {
|
||
req.payload.logger.warn(`[ipal] Favicon is ${width}×${height}px. Google requires ≥48×48 to ` + `display it in search results. Upload a larger square icon (96 or 192px).`);
|
||
}
|
||
if (width !== height) {
|
||
req.payload.logger.warn(`[ipal] Favicon is not square (${width}×${height}). Use a square icon ` + `so it isn't cropped in the browser tab or search results.`);
|
||
}
|
||
}
|
||
} catch {
|
||
// Media lookup failed — don't block the save over a validation warning.
|
||
}
|
||
return value;
|
||
};
|
||
|
||
//# sourceMappingURL=validateFavicon.js.map
|