folx-tv/server/static.ts
sebastjanartic 33671b7e94 Update image links to ensure compatibility with social media sharing
Updates image URLs in gallery data to use JPG versions instead of WebP for better compatibility with social media platforms like Facebook.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 517dfa7b-26ac-463d-a6e1-a58c6df97188
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: e03bc7c6-5eed-4f6c-9e9c-90776ba7f5d7
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/517dfa7b-26ac-463d-a6e1-a58c6df97188/EtK2Sno
Replit-Helium-Checkpoint-Created: true
2026-03-05 07:45:23 +00:00

74 lines
2.9 KiB
TypeScript

import express, { type Express } from "express";
import fs from "fs";
import path from "path";
import { storage } from "./storage";
function escapeHtml(str: string): string {
return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
}
function ogImageUrl(coverImage: string, baseUrl: string): string {
if (!coverImage) return "";
let imgPath = coverImage;
if (imgPath.endsWith(".webp")) {
imgPath = imgPath.replace(/\.webp$/, ".jpg");
}
return imgPath.startsWith("http") ? imgPath : `${baseUrl}${imgPath}`;
}
export function serveStatic(app: Express) {
const distPath = path.resolve(__dirname, "public");
if (!fs.existsSync(distPath)) {
throw new Error(
`Could not find the build directory: ${distPath}, make sure to build the client first`,
);
}
app.use(express.static(distPath));
app.use("/{*path}", async (req, res) => {
const url = req.originalUrl;
const indexPath = path.resolve(distPath, "index.html");
const articleMatch = url.match(/^\/article\/([^?#]+)/);
if (articleMatch) {
try {
const slug = decodeURIComponent(articleMatch[1]);
const article = await storage.getArticleBySlug(slug);
if (article) {
const host = req.get("host") || "folx.tv";
const protocol = req.get("x-forwarded-proto") || "https";
const baseUrl = `${protocol}://${host}`;
const articleUrl = `${baseUrl}/article/${article.slug}`;
const imageUrl = ogImageUrl(article.coverImage || "", baseUrl);
let template = await fs.promises.readFile(indexPath, "utf-8");
const ogTags = [
`<meta property="og:title" content="${escapeHtml(article.title)}" />`,
`<meta property="og:description" content="${escapeHtml(article.excerpt)}" />`,
`<meta property="og:type" content="article" />`,
`<meta property="og:url" content="${escapeHtml(articleUrl)}" />`,
imageUrl ? `<meta property="og:image" content="${escapeHtml(imageUrl)}" />` : "",
`<meta property="og:site_name" content="Folx Music Television" />`,
`<meta name="twitter:card" content="summary_large_image" />`,
`<meta name="twitter:title" content="${escapeHtml(article.title)}" />`,
`<meta name="twitter:description" content="${escapeHtml(article.excerpt)}" />`,
imageUrl ? `<meta name="twitter:image" content="${escapeHtml(imageUrl)}" />` : "",
`<title>${escapeHtml(article.title)} - Folx Music Television</title>`,
].filter(Boolean).join("\n ");
template = template.replace(/<meta property="og:[^"]*"[^>]*\/>\s*/g, "");
template = template.replace(/<title>.*?<\/title>/, ogTags);
res.status(200).set({ "Content-Type": "text/html" }).end(template);
return;
}
} catch (e) {
}
}
res.sendFile(indexPath);
});
}