diff --git a/README.md b/README.md index e804335..d7ce089 100644 --- a/README.md +++ b/README.md @@ -191,14 +191,6 @@ Static files served directly to the browser are within the `public` directory at ```md public/ -├── apple-touch-icon.png -├── favicon.ico -├── icon-192.png -├── icon-512.png -├── icon.svg -├── manifest.webmanifest -├── maskable_icon.png -├── maskable_icon_x512.png ├── scripts/ │ └── vendor/ │ ├── gsap/ # Animations powered by GSAP (GreenSock Animation Platform) diff --git a/package.json b/package.json index fce6831..06a0fd6 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "gsap": "^3.12.5", "html-minifier": "^4.0.0", "preline": "^2.0.3", + "sharp": "^0.33.3", + "sharp-ico": "^0.1.5", "tailwindcss": "^3.4.1" }, "devDependencies": { diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png deleted file mode 100644 index 709d945..0000000 Binary files a/public/apple-touch-icon.png and /dev/null differ diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 456b3a7..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/icon-192.png b/public/icon-192.png deleted file mode 100644 index 7a83b88..0000000 Binary files a/public/icon-192.png and /dev/null differ diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest deleted file mode 100644 index ac95964..0000000 --- a/public/manifest.webmanifest +++ /dev/null @@ -1,35 +0,0 @@ -{ - "short_name": "ScrewFast", - "name": "ScrewFast", - "icons": [ - { - "src": "/icon-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "any" - }, - { - "src": "/icon-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "any" - }, - { - "src": "/maskable_icon_x512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/maskable_icon.png", - "sizes": "1000x1000", - "type": "image/png", - "purpose": "maskable" - } - ], - "display": "minimal-ui", - "id": "/", - "start_url": "/", - "theme_color": "#FFEDD5", - "background_color": "#262626" - } \ No newline at end of file diff --git a/public/maskable_icon_x512.png b/public/maskable_icon_x512.png deleted file mode 100644 index 0c37558..0000000 Binary files a/public/maskable_icon_x512.png and /dev/null differ diff --git a/src/components/Meta.astro b/src/components/Meta.astro index d642a37..b3bd33e 100644 --- a/src/components/Meta.astro +++ b/src/components/Meta.astro @@ -1,4 +1,8 @@ --- +import { getImage } from "astro:assets"; +import faviconSvgSrc from "@/images/icon.svg"; +import faviconSrc from "@/images/icon.png"; + // Default properties for the Meta component. These values are used if props are not provided. // 'title' sets the default page title for the website. // 'meta' sets a default description meta tag to describe the page content. @@ -35,6 +39,20 @@ const ogDescription: string = "Equip your projects with ScrewFast's top-quality hardware tools and expert construction services. Trusted by industry leaders, ScrewFast offers simplicity, affordability, and reliability. Experience the difference with user-centric design and cutting-edge tools. Start exploring now!"; // Set the Open Graph description const URL: string = `${Astro.site}`; // Set the website URL in astro.config.mjs const socialImage: string = `${Astro.site}/social.png`; // Set the path for the social media image + +// Generate and optimize the favicon images +const faviconSvg = await getImage({ + src: faviconSvgSrc, + format: 'svg', +}); + +const appleTouchIcon = await getImage({ + src: faviconSrc, + width: 180, + height: 180, + format: 'png', +}); + --- - + - + - - + + diff --git a/public/maskable_icon.png b/src/images/icon-maskable.png similarity index 100% rename from public/maskable_icon.png rename to src/images/icon-maskable.png diff --git a/public/icon-512.png b/src/images/icon.png similarity index 100% rename from public/icon-512.png rename to src/images/icon.png diff --git a/public/icon.svg b/src/images/icon.svg similarity index 100% rename from public/icon.svg rename to src/images/icon.svg diff --git a/src/pages/favicon.ico.ts b/src/pages/favicon.ico.ts new file mode 100644 index 0000000..891b87c --- /dev/null +++ b/src/pages/favicon.ico.ts @@ -0,0 +1,28 @@ +import type { APIRoute } from "astro"; +import sharp from "sharp"; +import ico from "sharp-ico"; +import path from "node:path"; + +const faviconSrc = path.resolve("src/images/icon.png"); + +export const GET: APIRoute = async () => { + + // Resize the image to multiple sizes + const sizes = [16, 32, 48, 64, 128, 256]; + + const buffers = await Promise.all( + sizes.map(async (size) => { + return await sharp(faviconSrc) + .resize(size) + .toFormat("png") + .toBuffer(); + }) + ); + + // Convert the image to an ICO file + const icoBuffer = ico.encode(buffers); + + return new Response(icoBuffer, { + headers: { "Content-Type": "image/x-icon" }, + }); +}; diff --git a/src/pages/manifest.json.ts b/src/pages/manifest.json.ts new file mode 100644 index 0000000..bab70e0 --- /dev/null +++ b/src/pages/manifest.json.ts @@ -0,0 +1,58 @@ +import type { APIRoute, ImageMetadata } from "astro"; +import { getImage } from "astro:assets"; +import icon from "@/images/icon.png"; +import maskableIcon from "@/images/icon-maskable.png"; + +interface Favicon { + purpose: 'any' | 'maskable' | 'monochrome'; + src: ImageMetadata; + sizes: number[]; +} + +const sizes = [192, 512]; +const favicons: Favicon[] = [ + { + purpose: 'any', + src: icon, + sizes, + }, + { + purpose: 'maskable', + src: maskableIcon, + sizes, + }, +]; + +export const GET: APIRoute = async () => { + const icons = await Promise.all( + favicons.flatMap((favicon) => + favicon.sizes.map(async (size) => { + const image = await getImage({ + src: favicon.src, + width: size, + height: size, + format: "png", + }); + return { + src: image.src, + sizes: `${image.options.width}x${image.options.height}`, + type: `image/${image.options.format}`, + purpose: favicon.purpose, + }; + }), + ), + ); + + const manifest = { + short_name: "ScrewFast", + name: "ScrewFast", + icons, + display: "minimal-ui", + id: "some-unique-id", + start_url: "/", + theme_color: "#FFEDD5", + background_color: "#262626", + }; + + return new Response(JSON.stringify(manifest)); +};