Automatically optimize uploaded images for faster loading

Add image optimization module using sharp to automatically convert uploaded images to WebP format, generate thumbnails, and delete originals.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 517dfa7b-26ac-463d-a6e1-a58c6df97188
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 3972346d-247c-4913-af41-cab40bf9aec3
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/517dfa7b-26ac-463d-a6e1-a58c6df97188/drGbo1a
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
sebastjanartic
2026-02-28 21:12:36 +00:00
parent e64067a765
commit 3c23a20652
5 changed files with 584 additions and 7 deletions
+10 -3
View File
@@ -5,6 +5,7 @@ import { insertArticleSchema } from "@shared/schema";
import { seedDatabase } from "./seed";
import { generateDailyHoroscopes, getHoroscopesForToday, getOrGenerateHoroscope } from "./horoscope-generator";
import { analyzeAllArticleImages, getCachedFocalPoints } from "./focal-point";
import { optimizeImage } from "./image-optimizer";
import multer from "multer";
import path from "path";
import fs from "fs";
@@ -115,12 +116,18 @@ export async function registerRoutes(
res.status(204).send();
});
app.post("/api/upload", upload.single("image"), (req, res) => {
app.post("/api/upload", upload.single("image"), async (req, res) => {
if (!req.file) {
return res.status(400).json({ message: "No file uploaded" });
}
const url = `/uploads/${req.file.filename}`;
res.json({ url });
try {
const result = await optimizeImage(req.file.path);
res.json({ url: result.webp, thumb: result.thumb });
} catch (err) {
const url = `/uploads/${req.file.filename}`;
console.log("[image-optimizer] Optimization failed, using original:", (err as Error).message);
res.json({ url });
}
});
function bunnyFetch(path: string): Promise<any> {