Improve social media sharing by updating image generation
Updates social media image generation to use a new, dynamically generated image with a cache-busting parameter, ensuring up-to-date previews on platforms like WhatsApp and Viber. This includes enhancements to the SVG generation process using Sharp for optimized PNG output. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1/OdlP8Wj
This commit is contained in:
parent
3e2c11cf3a
commit
967aa3025c
@ -13,17 +13,24 @@
|
||||
<meta property="og:site_name" content="go4.video" />
|
||||
<meta property="og:locale" content="de_DE" />
|
||||
<meta property="og:url" content="https://go4video.replit.app/" />
|
||||
<meta property="og:image" content="https://go4video.replit.app/api/social-image" />
|
||||
<meta property="og:image" content="https://go4video.replit.app/api/social-image?v=2025" />
|
||||
<meta property="og:image:width" content="1200" />
|
||||
<meta property="og:image:height" content="630" />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
<meta property="og:image:alt" content="go4.video - Professional Video Streaming Platform" />
|
||||
|
||||
<!-- Twitter Card meta podatki -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@go4video" />
|
||||
<meta name="twitter:title" content="go4.video – Video-Welt von Folx TV" />
|
||||
<meta name="twitter:description" content="Video-Welt von Folx TV – immer bei dir" />
|
||||
<meta name="twitter:image" content="https://go4video.replit.app/api/social-image" />
|
||||
<meta name="twitter:image" content="https://go4video.replit.app/api/social-image?v=2025" />
|
||||
<meta name="twitter:image:alt" content="go4.video - Professional Video Streaming Platform" />
|
||||
|
||||
<!-- WhatsApp/Viber specifične oznake -->
|
||||
<meta property="og:image:secure_url" content="https://go4video.replit.app/api/social-image?v=2025" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
|
||||
<!-- Dodatni meta podatki za mobilne naprave -->
|
||||
<meta name="application-name" content="go4.video" />
|
||||
|
||||
@ -171,15 +171,18 @@ export default function VideoPage() {
|
||||
|
||||
updateMetaTag('og:title', currentVideo.title);
|
||||
updateMetaTag('og:description', currentVideo.description || `Watch ${currentVideo.title} on go4.video`);
|
||||
// Uporabljamo nov javni thumbnail API za social media deljenje
|
||||
const socialThumbnail = `${window.location.origin}/api/video-thumbnail/${currentVideo.id}`;
|
||||
// Uporabljan cache-busting parameter za social media refresh
|
||||
const timestamp = new Date().getTime();
|
||||
const socialThumbnail = `${window.location.origin}/api/video-thumbnail/${currentVideo.id}?v=${timestamp}`;
|
||||
updateMetaTag('og:image', socialThumbnail);
|
||||
updateMetaTag('og:image:width', '1200');
|
||||
updateMetaTag('og:image:height', '630');
|
||||
updateMetaTag('og:image:type', 'image/png');
|
||||
updateMetaTag('og:image:alt', `${currentVideo.title} - go4.video`);
|
||||
updateMetaTag('og:url', window.location.href);
|
||||
updateMetaTag('og:type', 'video.other');
|
||||
updateMetaTag('og:video:duration', currentVideo.duration.toString());
|
||||
updateMetaTag('og:site_name', 'go4.video');
|
||||
|
||||
// Update Twitter Card tags
|
||||
const updateTwitterTag = (name: string, content: string) => {
|
||||
@ -196,8 +199,8 @@ export default function VideoPage() {
|
||||
updateTwitterTag('twitter:title', currentVideo.title);
|
||||
updateTwitterTag('twitter:description', currentVideo.description || `Watch ${currentVideo.title} on go4.video`);
|
||||
updateTwitterTag('twitter:image', socialThumbnail);
|
||||
updateTwitterTag('twitter:image:width', '1200');
|
||||
updateTwitterTag('twitter:image:height', '630');
|
||||
updateTwitterTag('twitter:image:alt', `${currentVideo.title} - go4.video`);
|
||||
updateTwitterTag('twitter:site', '@go4video');
|
||||
}
|
||||
}, [currentVideo]);
|
||||
|
||||
|
||||
@ -701,32 +701,56 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Optimized social image endpoint
|
||||
app.get('/api/social-image', async (req, res) => {
|
||||
try {
|
||||
const fs = await import('fs');
|
||||
const path = await import('path');
|
||||
// Generate a modern social image with Sharp
|
||||
const width = 1200;
|
||||
const height = 630;
|
||||
|
||||
// Read the original social share image
|
||||
const imagePath = path.join(process.cwd(), 'client/public/go4-video-social-share.png');
|
||||
|
||||
if (!fs.existsSync(imagePath)) {
|
||||
return res.status(404).send('Social image not found');
|
||||
}
|
||||
|
||||
const originalImage = fs.readFileSync(imagePath);
|
||||
|
||||
// Optimize with Sharp for WhatsApp/social media (under 300KB)
|
||||
const optimizedBuffer = await sharp(originalImage)
|
||||
.resize(1200, 630, { fit: 'cover' })
|
||||
// Create a gradient background with text overlay
|
||||
const svg = `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#2D1B69;stop-opacity:1" />
|
||||
<stop offset="50%" style="stop-color:#6366f1;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#8b5cf6;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="logoGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#ffffff;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#ffffff;stop-opacity:0.8" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="${width}" height="${height}" fill="url(#bgGradient)"/>
|
||||
|
||||
<!-- Decorative elements -->
|
||||
<polygon points="100,100 200,200 50,200" fill="#ffffff" opacity="0.1"/>
|
||||
<polygon points="1000,150 1100,250 900,250" fill="#ffffff" opacity="0.08"/>
|
||||
<polygon points="200,400 300,500 100,500" fill="#ffffff" opacity="0.12"/>
|
||||
<polygon points="950,450 1050,550 850,550" fill="#ffffff" opacity="0.06"/>
|
||||
|
||||
<!-- Main logo -->
|
||||
<rect x="150" y="250" width="120" height="120" rx="30" fill="url(#logoGradient)"/>
|
||||
<polygon points="185,285 185,335 235,310" fill="#6366f1"/>
|
||||
|
||||
<!-- Main text -->
|
||||
<text x="320" y="290" font-family="Arial, sans-serif" font-size="64" font-weight="bold" fill="white">go4.video</text>
|
||||
<text x="320" y="340" font-family="Arial, sans-serif" font-size="28" fill="rgba(255,255,255,0.9)">Professional Video Streaming Platform</text>
|
||||
<text x="320" y="380" font-family="Arial, sans-serif" font-size="24" fill="rgba(255,255,255,0.7)">FOLX STADL • Geschichte des Liedes • Premium Content</text>
|
||||
</svg>`;
|
||||
|
||||
// Convert SVG to optimized PNG
|
||||
const buffer = await sharp(Buffer.from(svg))
|
||||
.png({
|
||||
quality: 80,
|
||||
compressionLevel: 9,
|
||||
progressive: true
|
||||
quality: 85,
|
||||
compressionLevel: 8,
|
||||
progressive: true
|
||||
})
|
||||
.toBuffer();
|
||||
|
||||
res.setHeader('Content-Type', 'image/png');
|
||||
res.setHeader('Cache-Control', 'public, max-age=86400'); // Cache for 24 hours
|
||||
res.setHeader('Content-Length', optimizedBuffer.length);
|
||||
res.send(optimizedBuffer);
|
||||
res.setHeader('Cache-Control', 'public, max-age=3600'); // Cache 1 hour for easier updates
|
||||
res.setHeader('Content-Length', buffer.length);
|
||||
res.send(buffer);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error generating optimized social image:', error);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user