From 87e07be40f31cc54a921f3449337e643a70b1b5a Mon Sep 17 00:00:00 2001
From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com>
Date: Sun, 31 Aug 2025 20:25:15 +0000
Subject: [PATCH] Add support for iOS app icons and PWA favicons
Updates `client/index.html` and `client/public/manifest.json` to include proper iOS icon links and specifies PNG format for favicons. Enhances the `/api/favicon` endpoint to generate PNG favicons using `sharp` for various sizes and includes the "go4" text for larger icons. Also adds `@types/compression` to `package.json` and `package-lock.json`.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ab9cd02a-d0b2-4288-9ceb-1964d0059648
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/ab9cd02a-d0b2-4288-9ceb-1964d0059648/mbX83Mu
---
client/index.html | 20 +++++------
client/public/manifest.json | 22 ++++++------
package-lock.json | 11 ++++++
package.json | 1 +
server/routes.ts | 71 +++++++++++++++++++++++++++----------
5 files changed, 85 insertions(+), 40 deletions(-)
diff --git a/client/index.html b/client/index.html
index c23688c..3fea956 100644
--- a/client/index.html
+++ b/client/index.html
@@ -37,19 +37,19 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
diff --git a/client/public/manifest.json b/client/public/manifest.json
index c7b172b..4f70c51 100644
--- a/client/public/manifest.json
+++ b/client/public/manifest.json
@@ -14,67 +14,67 @@
"prefer_related_applications": false,
"icons": [
{
- "src": "/api/favicon?size=57",
+ "src": "/api/favicon?size=57&format=png",
"sizes": "57x57",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=60",
+ "src": "/api/favicon?size=60&format=png",
"sizes": "60x60",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=72",
+ "src": "/api/favicon?size=72&format=png",
"sizes": "72x72",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=76",
+ "src": "/api/favicon?size=76&format=png",
"sizes": "76x76",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=114",
+ "src": "/api/favicon?size=114&format=png",
"sizes": "114x114",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=120",
+ "src": "/api/favicon?size=120&format=png",
"sizes": "120x120",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=144",
+ "src": "/api/favicon?size=144&format=png",
"sizes": "144x144",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=152",
+ "src": "/api/favicon?size=152&format=png",
"sizes": "152x152",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=180",
+ "src": "/api/favicon?size=180&format=png",
"sizes": "180x180",
"type": "image/png",
"purpose": "any"
},
{
- "src": "/api/favicon?size=192",
+ "src": "/api/favicon?size=192&format=png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
- "src": "/api/favicon?size=512",
+ "src": "/api/favicon?size=512&format=png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
diff --git a/package-lock.json b/package-lock.json
index 90eaa6c..8ad22d5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -43,6 +43,7 @@
"@radix-ui/react-tooltip": "^1.2.0",
"@tanstack/react-query": "^5.60.5",
"@types/bcryptjs": "^2.4.6",
+ "@types/compression": "^1.8.1",
"@types/memoizee": "^0.4.12",
"@types/multer": "^2.0.0",
"@types/node-fetch": "^2.6.13",
@@ -4326,6 +4327,16 @@
"integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==",
"license": "MIT"
},
+ "node_modules/@types/compression": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.8.1.tgz",
+ "integrity": "sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*",
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/connect": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
diff --git a/package.json b/package.json
index deecd02..b36a29d 100644
--- a/package.json
+++ b/package.json
@@ -45,6 +45,7 @@
"@radix-ui/react-tooltip": "^1.2.0",
"@tanstack/react-query": "^5.60.5",
"@types/bcryptjs": "^2.4.6",
+ "@types/compression": "^1.8.1",
"@types/memoizee": "^0.4.12",
"@types/multer": "^2.0.0",
"@types/node-fetch": "^2.6.13",
diff --git a/server/routes.ts b/server/routes.ts
index 20baae1..603bb05 100644
--- a/server/routes.ts
+++ b/server/routes.ts
@@ -13,6 +13,7 @@ import multer from "multer";
import { randomUUID } from "crypto";
import path from "path";
import session from "express-session";
+import sharp from "sharp";
// Extend express session
declare module "express-session" {
@@ -690,32 +691,64 @@ export async function registerRoutes(app: Express): Promise {
});
// Favicon generation endpoint
- app.get('/api/favicon', (req, res) => {
+ app.get('/api/favicon', async (req, res) => {
try {
const size = req.query.size ? parseInt(req.query.size as string) : 32;
+ const format = req.query.format as string || 'svg';
const padding = Math.max(2, size * 0.1);
const logoSize = size - (padding * 2);
const cornerRadius = Math.max(2, size * 0.15);
- // Generate SVG favicon with just the logo
- const svg = ``;
+ if (format === 'png') {
+ // Ustvarimo PNG ikono za iOS PWA
+ // Ustvarimo SVG za pretvorbo v PNG
+ const svg = ``;
- res.setHeader('Content-Type', 'image/svg+xml');
- res.setHeader('Cache-Control', 'public, max-age=86400'); // Cache for 24 hours
- res.send(svg);
+ // Pretvorimo SVG v PNG z Sharp
+ const pngBuffer = await sharp(Buffer.from(svg))
+ .png({ quality: 100, compressionLevel: 0 })
+ .toBuffer();
+
+ res.setHeader('Content-Type', 'image/png');
+ res.setHeader('Cache-Control', 'public, max-age=86400'); // Cache for 24 hours
+ res.send(pngBuffer);
+ } else {
+ // Originalni SVG favicon
+ const svg = ``;
+
+ res.setHeader('Content-Type', 'image/svg+xml');
+ res.setHeader('Cache-Control', 'public, max-age=86400'); // Cache for 24 hours
+ res.send(svg);
+ }
} catch (error) {
console.error('Error generating favicon:', error);
res.status(500).send('Error generating favicon');