Update social sharing buttons to use popup windows for a more reliable user experience. Adjust Facebook sharer URL format and ensure optimal OG image delivery by defaulting to JPG format and setting cache headers. Update image URLs in gallery data. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 1f7e7e89-a520-4970-9645-37daadc466dc Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 4a846f8c-2e0e-44e4-bcf6-7ac503fb3b19 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/1f7e7e89-a520-4970-9645-37daadc466dc/ZApZ5Qi Replit-Helium-Checkpoint-Created: true
94 lines
3.9 KiB
TypeScript
94 lines
3.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, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
}
|
|
|
|
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, {
|
|
setHeaders(res, filePath) {
|
|
if (filePath.endsWith("og-image.jpg") || filePath.includes("/uploads/")) {
|
|
res.setHeader("Cache-Control", "public, max-age=86400");
|
|
}
|
|
},
|
|
}));
|
|
|
|
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 finalImage = imageUrl || `${baseUrl}/og-image.jpg`;
|
|
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)}" />`,
|
|
`<meta property="og:image" content="${escapeHtml(finalImage)}" />`,
|
|
`<meta property="og:image:width" content="1200" />`,
|
|
`<meta property="og:image:height" content="630" />`,
|
|
`<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)}" />`,
|
|
`<meta name="twitter:image" content="${escapeHtml(finalImage)}" />`,
|
|
`<meta name="description" content="${escapeHtml(article.excerpt)}" />`,
|
|
`<title>${escapeHtml(article.title)} - Folx Music Television</title>`,
|
|
].join("\n ");
|
|
|
|
template = template.replace(/<meta property="og:[^>]*>\s*/g, "");
|
|
template = template.replace(/<meta name="description"[^>]*>\s*/g, "");
|
|
template = template.replace(/<meta name="twitter:[^>]*>\s*/g, "");
|
|
template = template.replace(/<title>[^<]*<\/title>/, ogTags);
|
|
|
|
res.status(200).set({ "Content-Type": "text/html" }).end(template);
|
|
return;
|
|
}
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
const host = req.get("host") || "folx.tv";
|
|
const protocol = req.get("x-forwarded-proto") || "https";
|
|
const baseUrl = `${protocol}://${host}`;
|
|
|
|
let template = await fs.promises.readFile(indexPath, "utf-8");
|
|
template = template.replace(/https:\/\/www\.folx\.tv\//g, `${baseUrl}/`);
|
|
template = template.replace(/https:\/\/www\.folx\.tv\/og-image\.jpg/g, `${baseUrl}/og-image.jpg`);
|
|
|
|
res.status(200).set({ "Content-Type": "text/html" }).end(template);
|
|
});
|
|
}
|