Add automatic Facebook sharing with video previews

Implement server-side Open Graph meta tags for videos and update video sharing functionality.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 401e2ec0-e00d-4f10-9d0e-60f3d479f9a5
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: 3500eb91-6967-423b-a9b5-22b380def61b
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/401e2ec0-e00d-4f10-9d0e-60f3d479f9a5/lPVBpdc
This commit is contained in:
sebastjanartic 2026-01-09 16:46:18 +00:00
parent 4f47d64e64
commit 3cec2d8f2e
3 changed files with 95 additions and 17 deletions

16
.replit
View File

@ -15,22 +15,6 @@ run = ["npm", "run", "start"]
localPort = 5000 localPort = 5000
externalPort = 80 externalPort = 80
[[ports]]
localPort = 33967
externalPort = 3002
[[ports]]
localPort = 34033
externalPort = 3001
[[ports]]
localPort = 35637
externalPort = 3000
[[ports]]
localPort = 41219
externalPort = 3003
[env] [env]
PORT = "5000" PORT = "5000"

View File

@ -315,6 +315,13 @@ export default function VideoPage() {
return `${baseUrl}/video/${currentVideo.id}`; return `${baseUrl}/video/${currentVideo.id}`;
}; };
// Facebook share URL uses special endpoint with proper OG meta tags
const getFacebookShareUrl = () => {
if (!currentVideo?.id) return window.location.origin;
const baseUrl = 'https://video.folx.tv';
return `${baseUrl}/share/video/${currentVideo.id}`;
};
const copyToClipboard = async () => { const copyToClipboard = async () => {
try { try {
await navigator.clipboard.writeText(getShareUrl()); await navigator.clipboard.writeText(getShareUrl());
@ -732,7 +739,7 @@ export default function VideoPage() {
{showShareMenu && ( {showShareMenu && (
<div className="absolute right-0 top-full mt-2 bg-gray-800 rounded-lg shadow-lg py-2 z-50 min-w-[200px]"> <div className="absolute right-0 top-full mt-2 bg-gray-800 rounded-lg shadow-lg py-2 z-50 min-w-[200px]">
<FacebookShareButton url={getShareUrl()}> <FacebookShareButton url={getFacebookShareUrl()}>
<div className="w-full px-4 py-2 text-left text-white hover:bg-gray-700 flex items-center gap-2 cursor-pointer"> <div className="w-full px-4 py-2 text-left text-white hover:bg-gray-700 flex items-center gap-2 cursor-pointer">
<FacebookIcon size={16} round /> <FacebookIcon size={16} round />
Facebook Facebook

View File

@ -1280,6 +1280,93 @@ export async function registerRoutes(app: Express): Promise<Server> {
} }
}); });
// Facebook/Social Media Share Page - Returns HTML with proper OG tags for video sharing
app.get('/share/video/:id', async (req, res) => {
try {
const { id } = req.params;
const video = await findVideoByAnyId(id);
if (!video) {
return res.status(404).send('Video not found');
}
const baseUrl = 'https://video.folx.tv';
const videoUrl = `${baseUrl}/video/${video.id}`;
// Get high-quality thumbnail for sharing (1200x630 is ideal for Facebook)
const thumbnailUrl = video.thumbnailUrl
? video.thumbnailUrl.replace('width=400&height=225', 'width=1200&height=630').replace('format=webp', 'format=jpg')
: `${baseUrl}/api/social-image`;
// Clean description for meta tags
const description = video.description
? video.description.substring(0, 200).replace(/[<>"']/g, '')
: `Gledajte ${video.title} na video.folx.tv - Najboljša glasba`;
const title = video.title || 'video.folx.tv';
// Return HTML page with OG tags that redirects to actual video
const html = `<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title} - video.folx.tv</title>
<!-- Open Graph meta tags for Facebook -->
<meta property="og:type" content="video.other">
<meta property="og:title" content="${title}">
<meta property="og:description" content="${description}">
<meta property="og:image" content="${thumbnailUrl}">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:type" content="image/jpeg">
<meta property="og:url" content="${videoUrl}">
<meta property="og:site_name" content="video.folx.tv">
<meta property="og:locale" content="de_DE">
<!-- Twitter Card meta tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="${title}">
<meta name="twitter:description" content="${description}">
<meta name="twitter:image" content="${thumbnailUrl}">
<!-- Redirect to actual video page for humans -->
<meta http-equiv="refresh" content="0;url=${videoUrl}">
<link rel="canonical" href="${videoUrl}">
<style>
body {
font-family: Arial, sans-serif;
background: #1a1a2e;
color: white;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
.container { text-align: center; }
a { color: #da234d; text-decoration: none; }
</style>
</head>
<body>
<div class="container">
<h1>Preusmerjanje...</h1>
<p>Če se ne preusmeri avtomatično, <a href="${videoUrl}">kliknite tukaj</a>.</p>
</div>
<script>window.location.href = "${videoUrl}";</script>
</body>
</html>`;
res.set('Content-Type', 'text/html');
res.send(html);
} catch (error) {
console.error('Error generating share page:', error);
res.status(500).send('Error generating share page');
}
});
// SEO - Sitemap XML with all video pages // SEO - Sitemap XML with all video pages
app.get('/sitemap.xml', async (req, res) => { app.get('/sitemap.xml', async (req, res) => {
try { try {