166 lines
6.2 KiB
JavaScript
166 lines
6.2 KiB
JavaScript
import { readFileSync, existsSync } from 'fs';
|
|
import { join } from 'path';
|
|
|
|
// SEO-Meta-Daten für verschiedene Routen
|
|
const seoData = {
|
|
'/': {
|
|
title: 'SingleChat - Chat, Single-Chat und Bildaustausch',
|
|
description: 'Willkommen auf SingleChat - deine erste Adresse für Chat, Single-Chat und Bildaustausch. Chatte mit Menschen aus aller Welt, finde neue Kontakte und teile Erinnerungen sicher und komfortabel.',
|
|
keywords: 'Chat, Single-Chat, Bildaustausch, Online-Chat, Singles, Kontakte, Community',
|
|
ogTitle: 'SingleChat - Chat, Single-Chat und Bildaustausch',
|
|
ogDescription: 'Willkommen auf SingleChat - deine erste Adresse für Chat, Single-Chat und Bildaustausch.',
|
|
ogType: 'website',
|
|
ogUrl: 'https://ypchat.net/',
|
|
ogImage: 'https://ypchat.net/static/favicon.png'
|
|
},
|
|
'/partners': {
|
|
title: 'Partner - SingleChat',
|
|
description: 'Unsere Partner und befreundete Seiten. Entdecke weitere interessante Angebote und Communities.',
|
|
keywords: 'Partner, Links, befreundete Seiten, Community',
|
|
ogTitle: 'Partner - SingleChat',
|
|
ogDescription: 'Unsere Partner und befreundete Seiten.',
|
|
ogType: 'website',
|
|
ogUrl: 'https://ypchat.net/partners',
|
|
ogImage: 'https://ypchat.net/static/favicon.png'
|
|
}
|
|
};
|
|
|
|
// HTML-Template für Pre-Rendering
|
|
function generateHTML(route, meta, __dirname) {
|
|
// Versuche, die gebaute index.html zu lesen
|
|
const distIndexPath = join(__dirname, '../docroot/dist/index.html');
|
|
let baseHTML;
|
|
|
|
if (existsSync(distIndexPath)) {
|
|
// Verwende die gebaute index.html (mit korrekten Asset-Pfaden von Vite)
|
|
baseHTML = readFileSync(distIndexPath, 'utf-8');
|
|
|
|
// Ersetze Meta-Tags in der gebauten HTML
|
|
baseHTML = baseHTML.replace(/<title>.*?<\/title>/, `<title>${meta.title}</title>`);
|
|
|
|
// Ersetze oder füge description hinzu
|
|
if (baseHTML.includes('<meta name="description"')) {
|
|
baseHTML = baseHTML.replace(/<meta name="description"[^>]*>/, `<meta name="description" content="${meta.description}">`);
|
|
} else {
|
|
baseHTML = baseHTML.replace('</head>', ` <meta name="description" content="${meta.description}">\n</head>`);
|
|
}
|
|
|
|
// Ersetze oder füge keywords hinzu
|
|
if (baseHTML.includes('<meta name="keywords"')) {
|
|
baseHTML = baseHTML.replace(/<meta name="keywords"[^>]*>/, `<meta name="keywords" content="${meta.keywords}">`);
|
|
} else {
|
|
baseHTML = baseHTML.replace('</head>', ` <meta name="keywords" content="${meta.keywords}">\n</head>`);
|
|
}
|
|
|
|
// Ersetze oder füge Open Graph Tags hinzu
|
|
const ogTags = `
|
|
<meta property="og:title" content="${meta.ogTitle}">
|
|
<meta property="og:description" content="${meta.ogDescription}">
|
|
<meta property="og:type" content="${meta.ogType}">
|
|
<meta property="og:url" content="${meta.ogUrl}">
|
|
<meta property="og:image" content="${meta.ogImage}">
|
|
<meta name="twitter:card" content="summary">
|
|
<meta name="twitter:title" content="${meta.ogTitle}">
|
|
<meta name="twitter:description" content="${meta.ogDescription}">
|
|
<meta name="twitter:image" content="${meta.ogImage}">
|
|
<link rel="canonical" href="${meta.ogUrl}">`;
|
|
|
|
// Entferne alte OG/Twitter/Canonical Tags falls vorhanden
|
|
baseHTML = baseHTML.replace(/<meta property="og:[^>]*>/g, '');
|
|
baseHTML = baseHTML.replace(/<meta name="twitter:[^>]*>/g, '');
|
|
baseHTML = baseHTML.replace(/<link rel="canonical"[^>]*>/g, '');
|
|
|
|
// Füge neue Tags vor </head> ein
|
|
baseHTML = baseHTML.replace('</head>', `${ogTags}\n</head>`);
|
|
|
|
// Füge robots meta hinzu falls nicht vorhanden
|
|
if (!baseHTML.includes('<meta name="robots"')) {
|
|
baseHTML = baseHTML.replace('</head>', ` <meta name="robots" content="index, follow">\n</head>`);
|
|
}
|
|
} else {
|
|
// Fallback: Gebaute index.html nicht gefunden - verwende SPA-Fallback
|
|
console.error('WARNUNG: Gebaute index.html nicht gefunden:', distIndexPath);
|
|
return null;
|
|
}
|
|
|
|
return baseHTML;
|
|
}
|
|
|
|
export function setupSEORoutes(app, __dirname) {
|
|
// Pre-Rendering für SEO-relevante Routen (nur in Production)
|
|
// In Development wird die normale index.html verwendet
|
|
const IS_PRODUCTION = process.env.NODE_ENV === 'production';
|
|
|
|
if (IS_PRODUCTION) {
|
|
// Pre-Rendering für Hauptseite
|
|
app.get('/', (req, res) => {
|
|
const meta = seoData['/'];
|
|
const html = generateHTML('/', meta, __dirname);
|
|
if (html) {
|
|
res.send(html);
|
|
} else {
|
|
// Fallback: Verwende die gebaute index.html direkt (ohne Meta-Tag-Anpassung)
|
|
const distIndexPath = join(__dirname, '../docroot/dist/index.html');
|
|
if (existsSync(distIndexPath)) {
|
|
res.sendFile(distIndexPath);
|
|
} else {
|
|
res.status(500).send('Gebaute index.html nicht gefunden. Bitte führe "npm run build" aus.');
|
|
}
|
|
}
|
|
});
|
|
|
|
// Pre-Rendering für Partners-Seite
|
|
app.get('/partners', (req, res) => {
|
|
const meta = seoData['/partners'];
|
|
const html = generateHTML('/partners', meta, __dirname);
|
|
if (html) {
|
|
res.send(html);
|
|
} else {
|
|
// Fallback: Verwende die gebaute index.html direkt (ohne Meta-Tag-Anpassung)
|
|
const distIndexPath = join(__dirname, '../docroot/dist/index.html');
|
|
if (existsSync(distIndexPath)) {
|
|
res.sendFile(distIndexPath);
|
|
} else {
|
|
res.status(500).send('Gebaute index.html nicht gefunden. Bitte führe "npm run build" aus.');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// robots.txt
|
|
app.get('/robots.txt', (req, res) => {
|
|
const robotsTxt = `User-agent: *
|
|
Allow: /
|
|
Allow: /partners
|
|
Disallow: /api/
|
|
Disallow: /static/logs/
|
|
|
|
Sitemap: https://ypchat.net/sitemap.xml
|
|
`;
|
|
res.type('text/plain');
|
|
res.send(robotsTxt);
|
|
});
|
|
|
|
// sitemap.xml
|
|
app.get('/sitemap.xml', (req, res) => {
|
|
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
<url>
|
|
<loc>https://ypchat.net/</loc>
|
|
<lastmod>${new Date().toISOString().split('T')[0]}</lastmod>
|
|
<changefreq>daily</changefreq>
|
|
<priority>1.0</priority>
|
|
</url>
|
|
<url>
|
|
<loc>https://ypchat.net/partners</loc>
|
|
<lastmod>${new Date().toISOString().split('T')[0]}</lastmod>
|
|
<changefreq>weekly</changefreq>
|
|
<priority>0.8</priority>
|
|
</url>
|
|
</urlset>`;
|
|
res.type('application/xml');
|
|
res.send(sitemap);
|
|
});
|
|
}
|
|
|