Files
e-tib.com/scripts/favicon.cjs
2026-05-07 19:14:34 +02:00

43 lines
1.6 KiB
JavaScript

const sharp = require('sharp');
async function run() {
try {
// Trim transparency to get the exact bounding box of the logo
const trimmed = sharp('public/assets/logo.png').trim();
const { info, data } = await trimmed.toBuffer({ resolveWithObject: true });
// Now data is the cropped image.
// The icon is usually the left-most part. It's often square. Let's assume the height of the trimmed image is the width of the icon.
const iconSize = info.height;
// Extract the left square
await sharp(data)
.extract({ left: 0, top: 0, width: iconSize, height: iconSize })
// Resize to a standard icon size, like 192x192
.resize(192, 192, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })
.toFile('public/icon.png');
// Create an apple-icon as well just in case
await sharp(data)
.extract({ left: 0, top: 0, width: iconSize, height: iconSize })
.resize(180, 180, { fit: 'contain', background: { r: 255, g: 255, b: 255, alpha: 1 } })
.toFile('public/apple-icon.png');
// Convert to .ico as well to replace the 0-byte favicon.ico
// sharp doesn't natively support .ico but we can just use icon.png and next.js handles it.
// However, I will delete the empty favicon.ico so Next.js falls back to icon.png
const fs = require('fs');
if (fs.existsSync('public/favicon.ico')) {
fs.unlinkSync('public/favicon.ico');
}
if (fs.existsSync('app/favicon.ico')) {
fs.unlinkSync('app/favicon.ico');
}
console.log('Successfully generated public/icon.png and public/apple-icon.png');
} catch (err) {
console.error(err);
}
}
run();