From 5306fde0be0408539d24c349d99554ef4bc1b89d Mon Sep 17 00:00:00 2001
From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com>
Date: Sat, 30 Aug 2025 22:09:11 +0000
Subject: [PATCH] Add custom images for sharing links on social media
Adds an API endpoint `/api/og-image` to generate dynamic Open Graph and Twitter Card images using SVG, and updates `index.html` to include these meta tags.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 051a65da-1176-4478-a61c-c662f2a15536
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/051a65da-1176-4478-a61c-c662f2a15536/9NQBiz8
---
client/index.html | 5 +++
server/generate-og-image.js | 78 +++++++++++++++++++++++++++++++++++++
server/routes.ts | 43 ++++++++++++++++++++
3 files changed, 126 insertions(+)
create mode 100644 server/generate-og-image.js
diff --git a/client/index.html b/client/index.html
index 4416255..33397e6 100644
--- a/client/index.html
+++ b/client/index.html
@@ -12,12 +12,17 @@
+
+
+
+
+
diff --git a/server/generate-og-image.js b/server/generate-og-image.js
new file mode 100644
index 0000000..c440a51
--- /dev/null
+++ b/server/generate-og-image.js
@@ -0,0 +1,78 @@
+const { createCanvas } = require('canvas');
+const fs = require('fs');
+const path = require('path');
+
+function generateOGImage() {
+ const canvas = createCanvas(1200, 630);
+ const ctx = canvas.getContext('2d');
+
+ // Background gradient
+ const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
+ gradient.addColorStop(0, 'hsl(250, 50%, 15%)');
+ gradient.addColorStop(1, 'hsl(240, 30%, 25%)');
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+
+ // Add geometric triangles
+ drawTriangle(ctx, 100, 100, 80, '#6366f1', 0.1);
+ drawTriangle(ctx, 1000, 200, 120, '#8b5cf6', 0.08);
+ drawTriangle(ctx, 200, 450, 60, '#6366f1', 0.12);
+ drawTriangle(ctx, 950, 500, 90, '#8b5cf6', 0.06);
+
+ // Main logo area
+ drawPlayButton(ctx, 300, 250, 60);
+
+ // Main title
+ ctx.fillStyle = 'white';
+ ctx.font = 'bold 72px Arial, sans-serif';
+ ctx.textAlign = 'left';
+ ctx.fillText('go4.video', 400, 330);
+
+ // Subtitle
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
+ ctx.font = '32px Arial, sans-serif';
+ ctx.fillText('Professional Video Streaming Platform', 400, 380);
+
+ // Bottom tagline
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';
+ ctx.font = '24px Arial, sans-serif';
+ ctx.fillText('Geschichte des Liedes • FOLX STADL • Premium Content', 400, 430);
+
+ return canvas.toBuffer('image/png');
+}
+
+function drawPlayButton(ctx, x, y, size) {
+ // Main circle
+ const gradient = ctx.createLinearGradient(x, y, x + size, y + size);
+ gradient.addColorStop(0, '#6366f1');
+ gradient.addColorStop(1, '#8b5cf6');
+
+ ctx.fillStyle = gradient;
+ ctx.beginPath();
+ ctx.roundRect(x, y, size, size, 15);
+ ctx.fill();
+
+ // Play triangle
+ ctx.fillStyle = 'white';
+ ctx.beginPath();
+ ctx.moveTo(x + size * 0.35, y + size * 0.25);
+ ctx.lineTo(x + size * 0.35, y + size * 0.75);
+ ctx.lineTo(x + size * 0.7, y + size * 0.5);
+ ctx.closePath();
+ ctx.fill();
+}
+
+function drawTriangle(ctx, x, y, size, color, opacity) {
+ ctx.save();
+ ctx.globalAlpha = opacity;
+ ctx.fillStyle = color;
+ ctx.beginPath();
+ ctx.moveTo(x, y);
+ ctx.lineTo(x + size, y + size * 0.8);
+ ctx.lineTo(x - size * 0.3, y + size);
+ ctx.closePath();
+ ctx.fill();
+ ctx.restore();
+}
+
+module.exports = { generateOGImage };
\ No newline at end of file
diff --git a/server/routes.ts b/server/routes.ts
index 2222f6d..d7aa8f2 100644
--- a/server/routes.ts
+++ b/server/routes.ts
@@ -646,6 +646,49 @@ export async function registerRoutes(app: Express): Promise {
res.sendFile(path.join(__dirname, "../client/public/ads.txt"));
});
+ // Open Graph image generation endpoint
+ app.get('/api/og-image', (req, res) => {
+ try {
+ // Generate SVG-based image for Open Graph
+ const svg = ``;
+
+ res.setHeader('Content-Type', 'image/svg+xml');
+ res.setHeader('Cache-Control', 'public, max-age=86400'); // Cache for 24 hours
+ res.send(svg);
+ } catch (error) {
+ console.error('Error generating OG image:', error);
+ res.status(500).send('Error generating image');
+ }
+ });
+
const httpServer = createServer(app);
return httpServer;
}