Improve video sharing on social media with rich previews and descriptions
Adds meta tags and server-side rendering for enhanced social sharing of videos. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 50814a1e-92e4-4968-856f-7bc7eedf5e8f Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/50814a1e-92e4-4968-856f-7bc7eedf5e8f/hUgv2Vz
This commit is contained in:
parent
a2b430c2e0
commit
eb7051843c
@ -3,6 +3,27 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
|
||||||
|
<title>VideoStream - Video Streaming Platform</title>
|
||||||
|
<meta name="description" content="Watch and discover amazing videos on VideoStream - your premium video streaming platform" />
|
||||||
|
|
||||||
|
<!-- Open Graph Meta Tags for Social Media -->
|
||||||
|
<meta property="og:title" content="VideoStream - Video Streaming Platform" />
|
||||||
|
<meta property="og:description" content="Watch and discover amazing videos on VideoStream - your premium video streaming platform" />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="" />
|
||||||
|
<meta property="og:image" content="" />
|
||||||
|
<meta property="og:image:width" content="1200" />
|
||||||
|
<meta property="og:image:height" content="630" />
|
||||||
|
<meta property="og:site_name" content="VideoStream" />
|
||||||
|
|
||||||
|
<!-- Twitter Card Meta Tags -->
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:title" content="VideoStream - Video Streaming Platform" />
|
||||||
|
<meta name="twitter:description" content="Watch and discover amazing videos on VideoStream - your premium video streaming platform" />
|
||||||
|
<meta name="twitter:image" content="" />
|
||||||
|
|
||||||
|
<!-- Facebook specific -->
|
||||||
|
<meta property="fb:app_id" content="" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@ -76,26 +76,42 @@ export default function VideoPage() {
|
|||||||
document.title = `${video.title} - VideoStream`;
|
document.title = `${video.title} - VideoStream`;
|
||||||
|
|
||||||
// Update meta tags for social sharing
|
// Update meta tags for social sharing
|
||||||
const updateMeta = (name: string, content: string) => {
|
const updateMeta = (name: string, content: string, property = true) => {
|
||||||
let meta = document.querySelector(`meta[property="${name}"]`) as HTMLMetaElement;
|
const selector = property ? `meta[property="${name}"]` : `meta[name="${name}"]`;
|
||||||
|
let meta = document.querySelector(selector) as HTMLMetaElement;
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
meta = document.createElement('meta');
|
meta = document.createElement('meta');
|
||||||
meta.setAttribute('property', name);
|
if (property) {
|
||||||
|
meta.setAttribute('property', name);
|
||||||
|
} else {
|
||||||
|
meta.setAttribute('name', name);
|
||||||
|
}
|
||||||
document.head.appendChild(meta);
|
document.head.appendChild(meta);
|
||||||
}
|
}
|
||||||
meta.content = content;
|
meta.content = content;
|
||||||
};
|
};
|
||||||
|
|
||||||
const shareUrl = `${window.location.origin}/video/${video.id}`;
|
const shareUrl = `${window.location.origin}/video/${video.id}`;
|
||||||
|
|
||||||
|
// Open Graph tags for Facebook
|
||||||
updateMeta('og:title', video.title);
|
updateMeta('og:title', video.title);
|
||||||
updateMeta('og:description', video.description || `Oglej si ta video na VideoStream`);
|
updateMeta('og:description', video.description || `Oglej si ta video na VideoStream`);
|
||||||
updateMeta('og:image', video.thumbnailUrl);
|
updateMeta('og:image', video.thumbnailUrl);
|
||||||
|
updateMeta('og:image:width', '1200');
|
||||||
|
updateMeta('og:image:height', '630');
|
||||||
|
updateMeta('og:image:type', 'image/jpeg');
|
||||||
updateMeta('og:url', shareUrl);
|
updateMeta('og:url', shareUrl);
|
||||||
updateMeta('og:type', 'video.other');
|
updateMeta('og:type', 'video.other');
|
||||||
updateMeta('twitter:card', 'summary_large_image');
|
updateMeta('og:site_name', 'VideoStream');
|
||||||
updateMeta('twitter:title', video.title);
|
|
||||||
updateMeta('twitter:description', video.description || `Oglej si ta video na VideoStream`);
|
// Standard meta tags
|
||||||
updateMeta('twitter:image', video.thumbnailUrl);
|
updateMeta('description', video.description || `Oglej si ta video na VideoStream`, false);
|
||||||
|
|
||||||
|
// Twitter Card tags
|
||||||
|
updateMeta('twitter:card', 'summary_large_image', false);
|
||||||
|
updateMeta('twitter:title', video.title, false);
|
||||||
|
updateMeta('twitter:description', video.description || `Oglej si ta video na VideoStream`, false);
|
||||||
|
updateMeta('twitter:image', video.thumbnailUrl, false);
|
||||||
}
|
}
|
||||||
}, [video]);
|
}, [video]);
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,63 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Serve video page with meta tags for social sharing
|
||||||
|
app.get("/video/:id", async (req, res) => {
|
||||||
|
try {
|
||||||
|
const video = await storage.getVideo(req.params.id);
|
||||||
|
if (!video) {
|
||||||
|
return res.redirect("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
const shareUrl = `${req.protocol}://${req.get('host')}/video/${video.id}`;
|
||||||
|
const html = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="sl">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
|
||||||
|
<title>${video.title} - VideoStream</title>
|
||||||
|
<meta name="description" content="${video.description || 'Oglej si ta video na VideoStream'}" />
|
||||||
|
|
||||||
|
<!-- Open Graph Meta Tags for Facebook -->
|
||||||
|
<meta property="og:title" content="${video.title}" />
|
||||||
|
<meta property="og:description" content="${video.description || 'Oglej si ta video na VideoStream'}" />
|
||||||
|
<meta property="og:type" content="video.other" />
|
||||||
|
<meta property="og:url" content="${shareUrl}" />
|
||||||
|
<meta property="og:image" content="${video.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:site_name" content="VideoStream" />
|
||||||
|
|
||||||
|
<!-- Twitter Card Meta Tags -->
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:title" content="${video.title}" />
|
||||||
|
<meta name="twitter:description" content="${video.description || 'Oglej si ta video na VideoStream'}" />
|
||||||
|
<meta name="twitter:image" content="${video.thumbnailUrl}" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Redirect to client-side app
|
||||||
|
window.location.href = '/';
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = '/video/${video.id}';
|
||||||
|
}, 100);
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
<script type="text/javascript" src="https://replit.com/public/js/replit-dev-banner.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
|
|
||||||
|
res.send(html);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error serving video page:", error);
|
||||||
|
res.redirect("/");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const httpServer = createServer(app);
|
const httpServer = createServer(app);
|
||||||
return httpServer;
|
return httpServer;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user