import fs from 'fs'
import path from 'path'
import sharp from 'sharp'
import ico from 'sharp-ico'
const imagesSourcePath = path.resolve(path.join(process.cwd(), 'src', 'images'))
const faviconSource = `${imagesSourcePath}/favicon-512.png`
const faviconSourceSvg = `${imagesSourcePath}/favicon.svg`
const outputWebRoot = path.resolve(path.join(process.cwd(), 'public'))
const outputManifest = path.resolve(
path.join(process.cwd(), 'public', 'manifest')
)
// All the sizes and meta we'll need
// https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs
const sizes = [32, 180, 192, 512]
const outputMeta = `
`
function createManifest(iconsizes: number[]) {
const manifest = {
name: 'matthias kretschmann',
short_name: 'mk',
display: 'standalone',
start_url: '/',
icons: iconsizes.map((size) => ({
src: `/manifest/favicon-${size}.png`,
type: 'image/png',
sizes: `${size}x${size}`
}))
}
fs.writeFileSync(
`${outputManifest}/manifest.webmanifest`,
JSON.stringify(manifest)
)
}
function nuke() {
fs.rmSync(outputManifest, { recursive: true, force: true })
fs.rmSync(`${outputWebRoot}/apple-touch-icon.png`, { force: true })
fs.rmSync(`${outputWebRoot}/favicon.ico`, { force: true })
fs.rmSync(`${outputWebRoot}/favicon.svg`, { force: true })
fs.mkdirSync(outputManifest, { recursive: true })
}
async function buildFavicons() {
try {
// Nuke all & create output folder first
nuke()
// copy over the svg, as it's handcrafted
fs.copyFileSync(faviconSourceSvg, `${outputWebRoot}/favicon.svg`)
// generate all the rest
await Promise.all(
sizes.map(async (size) => {
let destination = `${outputManifest}/favicon-${size}.png`
if (size === 180) destination = `${outputWebRoot}/apple-touch-icon.png`
// 32px size only used for favicon.ico
if (size === 32) {
await ico.sharpsToIco(
[sharp(faviconSource)],
`${outputWebRoot}/favicon.ico`,
{ sizes: [32, 24, 16], resizeOptions: {} }
)
fs.rmSync(destination, { force: true })
} else {
await sharp(faviconSource).resize(size, size).toFile(destination)
}
})
)
// write out manifest
createManifest([192, 512])
console.log(`
-----------------------------
Favicon generation complete!
-----------------------------
Add this to src/components/Meta/Favicon.tsx:
${outputMeta}
`)
} catch (error) {
console.error(error.message)
}
}
buildFavicons()