Serve custom social sharing image instead of generating one
Update the /api/social-image endpoint to serve a custom PNG image from the public directory instead of dynamically generating an SVG. The route now checks for the existence of 'social-share-image.png' and serves it with appropriate headers, falling back to generation if the custom image is not found. 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/3dnI7Tc
This commit is contained in:
parent
59db5be03f
commit
30ef682140
Binary file not shown.
|
After Width: | Height: | Size: 870 KiB |
BIN
client/public/social-share-image.png
Normal file
BIN
client/public/social-share-image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 870 KiB |
@ -732,73 +732,59 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
// Optimized social image endpoint
|
||||
// Custom social image endpoint - serves your beautiful uploaded image
|
||||
app.get('/api/social-image', async (req, res) => {
|
||||
try {
|
||||
console.log('📸 Generating social image...');
|
||||
console.log('📸 Serving custom social image...');
|
||||
|
||||
// Generate a large, high-quality social image with Sharp
|
||||
const width = 1200;
|
||||
const height = 630;
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// Create a more prominent social media image
|
||||
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:#1a1a2e;stop-opacity:1" />
|
||||
<stop offset="30%" style="stop-color:#16213e;stop-opacity:1" />
|
||||
<stop offset="70%" 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.9" />
|
||||
</linearGradient>
|
||||
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<dropShadow dx="2" dy="4" stdDeviation="3" flood-color="#000000" flood-opacity="0.3"/>
|
||||
</filter>
|
||||
</defs>
|
||||
const imagePath = path.join(__dirname, '..', 'client', 'public', 'social-share-image.png');
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="${width}" height="${height}" fill="url(#bgGradient)"/>
|
||||
// Check if custom image exists
|
||||
if (fs.existsSync(imagePath)) {
|
||||
console.log('✅ Custom social image found, serving...');
|
||||
const imageBuffer = fs.readFileSync(imagePath);
|
||||
|
||||
<!-- Large decorative triangles -->
|
||||
<polygon points="0,0 300,0 150,150" fill="#ffffff" opacity="0.05"/>
|
||||
<polygon points="900,0 1200,0 1200,300" fill="#ffffff" opacity="0.04"/>
|
||||
<polygon points="0,330 200,630 0,630" fill="#ffffff" opacity="0.06"/>
|
||||
<polygon points="1000,430 1200,630 1000,630" fill="#ffffff" opacity="0.05"/>
|
||||
res.setHeader('Content-Type', 'image/png');
|
||||
res.setHeader('Content-Length', imageBuffer.length);
|
||||
res.setHeader('Cache-Control', 'public, max-age=3600'); // Cache for 1 hour
|
||||
res.setHeader('Access-Control-Allow-Origin', '*'); // Allow cross-origin for social media
|
||||
res.send(imageBuffer);
|
||||
} else {
|
||||
console.log('⚠️ Custom image not found, generating fallback...');
|
||||
// Fallback to generated image if custom not found
|
||||
const width = 1200;
|
||||
const height = 630;
|
||||
|
||||
<!-- Large central logo -->
|
||||
<rect x="100" y="215" width="200" height="200" rx="50" fill="url(#logoGradient)" filter="url(#shadow)"/>
|
||||
<polygon points="150,265 150,365 250,315" fill="#6366f1"/>
|
||||
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:#6366f1;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#8b5cf6;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Large prominent text -->
|
||||
<text x="350" y="280" font-family="Arial, sans-serif" font-size="84" font-weight="bold" fill="white" filter="url(#shadow)">go4.video</text>
|
||||
<text x="350" y="330" font-family="Arial, sans-serif" font-size="32" fill="rgba(255,255,255,0.95)" filter="url(#shadow)">Professional Video Streaming</text>
|
||||
<text x="350" y="370" font-family="Arial, sans-serif" font-size="28" fill="rgba(255,255,255,0.8)">FOLX STADL • Geschichte des Liedes</text>
|
||||
<text x="350" y="410" font-family="Arial, sans-serif" font-size="24" fill="rgba(255,255,255,0.7)">Premium Video Content Platform</text>
|
||||
</svg>`;
|
||||
<rect width="${width}" height="${height}" fill="url(#bgGradient)"/>
|
||||
<text x="600" y="340" font-family="Arial, sans-serif" font-size="80" font-weight="bold" fill="white" text-anchor="middle">go4.video</text>
|
||||
<text x="600" y="390" font-family="Arial, sans-serif" font-size="32" fill="rgba(255,255,255,0.9)" text-anchor="middle">Video-Welt von Folx TV</text>
|
||||
</svg>`;
|
||||
|
||||
// Convert SVG to high-quality PNG with better compression
|
||||
const buffer = await sharp(Buffer.from(svg))
|
||||
.png({
|
||||
quality: 90,
|
||||
compressionLevel: 6,
|
||||
progressive: true
|
||||
})
|
||||
.toBuffer();
|
||||
const buffer = await sharp(Buffer.from(svg))
|
||||
.png({ quality: 95, compressionLevel: 6 })
|
||||
.toBuffer();
|
||||
|
||||
console.log(`📸 Social image generated: ${buffer.length} bytes`);
|
||||
|
||||
res.setHeader('Content-Type', 'image/png');
|
||||
res.setHeader('Cache-Control', 'public, max-age=1800'); // Cache 30 minutes
|
||||
res.setHeader('Content-Length', buffer.length);
|
||||
res.setHeader('Access-Control-Allow-Origin', '*'); // Allow cross-origin for social media
|
||||
res.send(buffer);
|
||||
res.setHeader('Content-Type', 'image/png');
|
||||
res.setHeader('Content-Length', buffer.length);
|
||||
res.setHeader('Cache-Control', 'public, max-age=3600');
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
res.send(buffer);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error generating social image:', error);
|
||||
res.status(500).send('Error generating social image');
|
||||
console.error('❌ Error serving social image:', error);
|
||||
res.status(500).send('Error serving social image');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user