From 18493af6dcac00ef407bdd8ac337e3b0d3f69578 Mon Sep 17 00:00:00 2001 From: Bert Hausmans Date: Tue, 6 Jan 2026 03:05:38 +0100 Subject: [PATCH] Add OG meta tags for participant access pages --- server/index.ts | 75 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/server/index.ts b/server/index.ts index 079cfa1..4a9c645 100644 --- a/server/index.ts +++ b/server/index.ts @@ -6,7 +6,7 @@ import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; -import { initializeDatabase, questionnaireOps } from './database.js'; +import { initializeDatabase, questionnaireOps, participantOps } from './database.js'; import authRoutes from './routes/auth.js'; import adminRoutes from './routes/admin.js'; import questionnaireRoutes from './routes/questionnaire.js'; @@ -76,6 +76,21 @@ if (isProduction) { const clientPath = path.join(__dirname, '../client'); app.use(express.static(clientPath)); + // Helper function to generate OG tags HTML + function generateOgTags(baseUrl: string, pageUrl: string, title: string, description: string, ogImageUrl: string | null): string { + return ` + + + + + ${ogImageUrl ? `` : ''} + + + + ${ogImageUrl ? `` : ''} + `; + } + // Dynamic OG meta tags for questionnaire pages app.get('/q/:slug', (req, res) => { const questionnaire = questionnaireOps.findBySlug(req.params.slug); @@ -101,17 +116,53 @@ if (isProduction) { ogImageUrl = `${baseUrl}${ogImageUrl}`; } - const ogTags = ` - - - - - ${ogImageUrl ? `` : ''} - - - - ${ogImageUrl ? `` : ''} - `; + const ogTags = generateOgTags(baseUrl, pageUrl, title, description, ogImageUrl); + + // Insert OG tags before + html = html.replace('', `${ogTags}`); + + // Update title + html = html.replace(/.*?<\/title>/, `<title>${title} - Activiteiten Inventaris`); + + res.send(html); + }); + + // Dynamic OG meta tags for participant access pages + app.get('/q/access/:token', (req, res) => { + const participant = participantOps.findByToken(req.params.token); + const indexPath = path.join(clientPath, 'index.html'); + + if (!participant) { + res.sendFile(indexPath); + return; + } + + const questionnaire = questionnaireOps.findById(participant.questionnaire_id); + if (!questionnaire) { + res.sendFile(indexPath); + return; + } + + // Read the index.html template + let html = fs.readFileSync(indexPath, 'utf-8'); + + // Build meta tags + const baseUrl = `${req.protocol}://${req.get('host')}`; + const pageUrl = `${baseUrl}/q/access/${participant.token}`; + const title = questionnaire.title; + + // Get first name from participant name + const firstName = participant.name.trim().split(/\s+/)[0] || participant.name; + const description = questionnaire.description + || `Hoi ${firstName}! Voeg je ideeën toe en stem op activiteiten.`; + + // Make image URL absolute if it's a relative path + let ogImageUrl = questionnaire.og_image; + if (ogImageUrl && ogImageUrl.startsWith('/')) { + ogImageUrl = `${baseUrl}${ogImageUrl}`; + } + + const ogTags = generateOgTags(baseUrl, pageUrl, title, description, ogImageUrl); // Insert OG tags before html = html.replace('', `${ogTags}`);