Improve page titles and meta descriptions for better search engine visibility

Updates titles, meta descriptions, and Open Graph tags across various pages and API responses for improved SEO and language consistency.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 401e2ec0-e00d-4f10-9d0e-60f3d479f9a5
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: b39b5688-81f4-4af3-b05c-9c9e8c4350ff
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/401e2ec0-e00d-4f10-9d0e-60f3d479f9a5/qFrskyV
This commit is contained in:
sebastjanartic 2026-02-13 17:39:39 +00:00
parent f8ed358592
commit 120fd478e8
9 changed files with 338 additions and 41 deletions

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no, viewport-fit=cover" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no, viewport-fit=cover" />
<title>video.folx.tv FOLX.TV Video Platform</title> <title>Folx TV - Video</title>
<!-- Google Consent Management Platform --> <!-- Google Consent Management Platform -->
<script> <script>
@ -18,14 +18,14 @@
</script> </script>
<script async src="https://fundingchoicesmessages.google.com/i/pub-4465464714854276?ers=1" nonce="temp-nonce"></script> <script async src="https://fundingchoicesmessages.google.com/i/pub-4465464714854276?ers=1" nonce="temp-nonce"></script>
<script nonce="temp-nonce">(function() {function signalGooglefcPresent() {if (!window.frames['googlefcPresent']) {if (document.body) {const iframe = document.createElement('iframe'); iframe.style = 'width: 0; height: 0; border: none; z-index: -1000; left: -1000px; top: -1000px;'; iframe.style.display = 'none'; iframe.name = 'googlefcPresent'; document.body.appendChild(iframe);} else {setTimeout(signalGooglefcPresent, 0);}}}signalGooglefcPresent();})();</script> <script nonce="temp-nonce">(function() {function signalGooglefcPresent() {if (!window.frames['googlefcPresent']) {if (document.body) {const iframe = document.createElement('iframe'); iframe.style = 'width: 0; height: 0; border: none; z-index: -1000; left: -1000px; top: -1000px;'; iframe.style.display = 'none'; iframe.name = 'googlefcPresent'; document.body.appendChild(iframe);} else {setTimeout(signalGooglefcPresent, 0);}}}signalGooglefcPresent();})();</script>
<meta name="description" content="FOLX.TV Video Platform Musik, Unterhaltung und Live-Streaming. Jetzt deutsche Schlager, Volksmusik und mehr ansehen!" /> <meta name="description" content="Folx TV - Nummer 1 in Europa für Volksmusik und Schlager. Video Streaming Plattform mit Musik, Unterhaltung und Live-Streaming." />
<!-- Google Search Console verification --> <!-- Google Search Console verification -->
<meta name="google-site-verification" content="YcRvFNGnAbAnlhQvhODVJOaqHLVdOKnpCqk7oH-xeKE" /> <meta name="google-site-verification" content="YcRvFNGnAbAnlhQvhODVJOaqHLVdOKnpCqk7oH-xeKE" />
<!-- Open Graph meta podatki za družbena omrežja in mobilne aplikacije --> <!-- Open Graph meta podatki za družbena omrežja in mobilne aplikacije -->
<meta property="og:title" content="video.folx.tv FOLX.TV Video Platform" /> <meta property="og:title" content="Folx TV - Video" />
<meta property="og:description" content="FOLX.TV Video Platform Musik, Unterhaltung und Live-Streaming. Jetzt ansehen!" /> <meta property="og:description" content="Folx TV - Nummer 1 in Europa für Volksmusik und Schlager. Musik, Unterhaltung und Live-Streaming." />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:site_name" content="video.folx.tv" /> <meta property="og:site_name" content="video.folx.tv" />
<meta property="og:locale" content="de_DE" /> <meta property="og:locale" content="de_DE" />
@ -34,15 +34,15 @@
<meta property="og:image:width" content="1200" /> <meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" /> <meta property="og:image:height" content="630" />
<meta property="og:image:type" content="image/png" /> <meta property="og:image:type" content="image/png" />
<meta property="og:image:alt" content="video.folx.tv FOLX.TV Video Platform" /> <meta property="og:image:alt" content="Folx TV - Video" />
<!-- Twitter Card meta podatki --> <!-- Twitter Card meta podatki -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@folxtv" /> <meta name="twitter:site" content="@folxtv" />
<meta name="twitter:title" content="video.folx.tv FOLX.TV Video Platform" /> <meta name="twitter:title" content="Folx TV - Video" />
<meta name="twitter:description" content="FOLX.TV Video Platform Musik, Unterhaltung und Live-Streaming. Jetzt ansehen!" /> <meta name="twitter:description" content="Folx TV - Nummer 1 in Europa für Volksmusik und Schlager. Musik, Unterhaltung und Live-Streaming." />
<meta name="twitter:image" id="twitter-image" content="https://video.folx.tv/api/social-image" /> <meta name="twitter:image" id="twitter-image" content="https://video.folx.tv/api/social-image" />
<meta name="twitter:image:alt" content="video.folx.tv FOLX.TV Video Platform" /> <meta name="twitter:image:alt" content="Folx TV - Video" />
<!-- WhatsApp/Viber specifične oznake --> <!-- WhatsApp/Viber specifične oznake -->
<meta property="og:image:secure_url" id="og-image-secure" content="https://video.folx.tv/api/social-image" /> <meta property="og:image:secure_url" id="og-image-secure" content="https://video.folx.tv/api/social-image" />
@ -95,9 +95,9 @@
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "WebSite", "@type": "WebSite",
"name": "video.folx.tv", "name": "video.folx.tv",
"alternateName": "FOLX.TV Video Platform", "alternateName": "Folx TV - Video",
"url": "https://video.folx.tv", "url": "https://video.folx.tv",
"description": "Deutsche Video Streaming Plattform mit Musik, Unterhaltung und Live-Streaming", "description": "Folx TV - Nummer 1 in Europa für Volksmusik und Schlager. Video Streaming Plattform mit Musik, Unterhaltung und Live-Streaming.",
"inLanguage": "de", "inLanguage": "de",
"potentialAction": { "potentialAction": {
"@type": "SearchAction", "@type": "SearchAction",

View File

@ -79,6 +79,14 @@ export default function FolxStadlPage() {
} }
}; };
useEffect(() => {
document.title = 'FOLX STADL - Die große Volksmusik Show | Folx TV - Video';
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', 'FOLX STADL - Die beliebte Volksmusik- und Schlagershow. Mit Angela Wiedl, Oswald Sattler, Die Grubertaler und vielen mehr. Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.');
}
}, []);
if (isLoading) { if (isLoading) {
return ( return (
<div className="min-h-screen bg-bunny-dark flex items-center justify-center"> <div className="min-h-screen bg-bunny-dark flex items-center justify-center">

View File

@ -81,6 +81,14 @@ export default function GeschichteLiedPage() {
} }
}; };
useEffect(() => {
document.title = 'Die Geschichte des Liedes - Musikdokumentation | Folx TV - Video';
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', 'Die Geschichte des Liedes - Entdecken Sie die Entstehung der beliebtesten Volksmusik- und Schlagerlieder. Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.');
}
}, []);
if (isLoading) { if (isLoading) {
return ( return (
<div className="min-h-screen bg-bunny-dark flex items-center justify-center"> <div className="min-h-screen bg-bunny-dark flex items-center justify-center">

View File

@ -81,6 +81,14 @@ export default function GipfelstammtischPage() {
} }
}; };
useEffect(() => {
document.title = 'Gipfelstammtisch - Volksmusik Talkshow | Folx TV - Video';
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', 'Gipfelstammtisch - Die gemütliche Volksmusik-Talkshow. Gespräche mit Stars der Volksmusik- und Schlagerszene. Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.');
}
}, []);
if (isLoading) { if (isLoading) {
return ( return (
<div className="min-h-screen bg-bunny-dark flex items-center justify-center"> <div className="min-h-screen bg-bunny-dark flex items-center justify-center">

View File

@ -38,11 +38,11 @@ export default function LivePage() {
useEffect(() => { useEffect(() => {
// Set page meta tags // Set page meta tags
document.title = 'LIVE Stream | video.folx.tv'; document.title = 'LIVE Stream | Folx TV - Video';
const metaDescription = document.querySelector('meta[name="description"]'); const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) { if (metaDescription) {
metaDescription.setAttribute('content', 'Live stream on video.folx.tv - watch exclusive content in real time.'); metaDescription.setAttribute('content', 'Live Stream auf Folx TV - Schauen Sie exklusive Inhalte in Echtzeit. Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.');
} }
const updateMetaTag = (property: string, content: string) => { const updateMetaTag = (property: string, content: string) => {
@ -55,8 +55,8 @@ export default function LivePage() {
meta.setAttribute('content', content); meta.setAttribute('content', content);
}; };
updateMetaTag('og:title', 'LIVE Stream - video.folx.tv'); updateMetaTag('og:title', 'LIVE Stream | Folx TV - Video');
updateMetaTag('og:description', 'Live stream on video.folx.tv - watch exclusive content in real time.'); updateMetaTag('og:description', 'Live Stream auf Folx TV - Schauen Sie exklusive Inhalte in Echtzeit. Nummer 1 in Europa für Volksmusik und Schlager.');
updateMetaTag('og:type', 'video.other'); updateMetaTag('og:type', 'video.other');
}, []); }, []);

View File

@ -19,11 +19,11 @@ export default function PlayerPage() {
const videos = (videosData && Array.isArray((videosData as any).videos)) ? (videosData as any).videos : []; const videos = (videosData && Array.isArray((videosData as any).videos)) ? (videosData as any).videos : [];
useEffect(() => { useEffect(() => {
document.title = 'Professional Player | video.folx.tv'; document.title = 'Professional Player | Folx TV - Video';
const metaDescription = document.querySelector('meta[name="description"]'); const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) { if (metaDescription) {
metaDescription.setAttribute('content', 'Professional Video Player mit Streaming-Funktionen auf video.folx.tv'); metaDescription.setAttribute('content', 'Professioneller Video Player mit Overlay Graphics und Streaming-Funktionen. Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.');
} }
}, []); }, []);

View File

@ -198,14 +198,22 @@ export default function VideoPage() {
useEffect(() => { useEffect(() => {
if (currentVideo) { if (currentVideo) {
// Update page title // Update page title
document.title = `${currentVideo.title} | video.folx.tv`; document.title = `${currentVideo.title} | Folx TV - Video`;
// Update meta description with original or rich content // Update meta description with original or rich content
const metaDescription = document.querySelector('meta[name="description"]'); const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) { if (metaDescription) {
const descriptionContent = currentVideo.description && currentVideo.description.trim() !== '' const descriptionContent = currentVideo.description && currentVideo.description.trim() !== ''
? currentVideo.description ? currentVideo.description
: `${currentVideo.title} - Professionelle Video-Streaming-Plattform mit exklusivem Content von FOLX STADL, Geschichte des Liedes und weiteren Premium-Inhalten auf video.folx.tv.`; : (() => {
const t = currentVideo.title || '';
let a = '';
if (t.includes('')) a = t.split('')[0].trim();
else if (t.includes(' - ')) a = t.split(' - ')[0].trim();
return a
? `${t} - Jetzt ansehen auf Folx TV. Nummer 1 in Europa für Volksmusik und Schlager.`
: `${t} - Jetzt ansehen auf Folx TV. Nummer 1 in Europa für Volksmusik und Schlager.`;
})();
metaDescription.setAttribute('content', descriptionContent); metaDescription.setAttribute('content', descriptionContent);
} }
@ -225,7 +233,7 @@ export default function VideoPage() {
// Use original description if available, otherwise create rich description // Use original description if available, otherwise create rich description
const richDescription = currentVideo.description && currentVideo.description.trim() !== '' const richDescription = currentVideo.description && currentVideo.description.trim() !== ''
? currentVideo.description ? currentVideo.description
: `${currentVideo.title} - Professionelle Video-Streaming-Plattform mit exklusivem Content von FOLX STADL, Geschichte des Liedes und weiteren Premium-Inhalten auf video.folx.tv.`; : `${currentVideo.title} - Jetzt ansehen auf Folx TV. Nummer 1 in Europa für Volksmusik und Schlager.`;
updateMetaTag('og:description', richDescription); updateMetaTag('og:description', richDescription);
// For social media, use direct Bunny.net thumbnail if available, otherwise fallback to our endpoint // For social media, use direct Bunny.net thumbnail if available, otherwise fallback to our endpoint

View File

@ -50,6 +50,14 @@ export default function Home() {
refetchInterval: 120000 refetchInterval: 120000
}); });
useEffect(() => {
document.title = 'Folx TV - Video';
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', 'Folx TV - Nummer 1 in Europa für Volksmusik und Schlager. Video Streaming Plattform mit Musik, Unterhaltung und Live-Streaming.');
}
}, []);
// Update videos when new data comes in // Update videos when new data comes in
useEffect(() => { useEffect(() => {
if (videosResponse) { if (videosResponse) {

View File

@ -146,12 +146,63 @@ export async function registerRoutes(app: Express): Promise<Server> {
.replace(/format=webp/gi, 'format=jpg'); .replace(/format=webp/gi, 'format=jpg');
} }
// Extract artist name from title (format: "Artist Song" or "Artist - Song")
const titleStr = video.title || '';
let artistName = '';
let songName = titleStr;
if (titleStr.includes('')) {
const parts = titleStr.split('');
artistName = parts[0].trim();
songName = parts.slice(1).join('').trim();
} else if (titleStr.includes(' - ')) {
const parts = titleStr.split(' - ');
artistName = parts[0].trim();
songName = parts.slice(1).join(' - ').trim();
}
// Clean description for meta tags // Clean description for meta tags
const description = video.description const description = video.description
? video.description.substring(0, 200).replace(/[<>"']/g, '') ? video.description.substring(0, 200).replace(/[<>"']/g, '')
: `Schauen Sie ${video.title} auf video.folx.tv - Die beste Musik`; : artistName
? `${artistName} ${songName}. Jetzt ansehen auf Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.`
: `${titleStr} auf Folx TV ansehen - Nummer 1 in Europa für Volksmusik und Schlager.`;
const title = video.title || 'video.folx.tv'; const title = video.title || 'Folx TV - Video';
const keywords = artistName
? `${artistName}, ${songName}, Volksmusik, Schlager, Folx TV, Musikvideo`
: `${titleStr}, Volksmusik, Schlager, Folx TV`;
// JSON-LD structured data for video with artist
const jsonLd: any = {
"@context": "https://schema.org",
"@type": "VideoObject",
"name": title,
"description": description,
"thumbnailUrl": thumbnailUrl,
"uploadDate": video.createdAt ? new Date(video.createdAt).toISOString() : new Date().toISOString(),
"duration": video.duration ? `PT${Math.floor(video.duration / 60)}M${video.duration % 60}S` : undefined,
"contentUrl": videoUrl,
"embedUrl": videoUrl,
"interactionStatistic": {
"@type": "InteractionCounter",
"interactionType": "https://schema.org/WatchAction",
"userInteractionCount": video.views || 0
},
"publisher": {
"@type": "Organization",
"name": "FOLX.TV",
"url": "https://folx.tv"
},
"inLanguage": "de"
};
if (artistName) {
jsonLd["byArtist"] = {
"@type": "MusicGroup",
"name": artistName
};
jsonLd["@type"] = "MusicVideoObject";
}
// Return HTML page with OG tags for crawlers // Return HTML page with OG tags for crawlers
const html = `<!DOCTYPE html> const html = `<!DOCTYPE html>
@ -159,9 +210,10 @@ export async function registerRoutes(app: Express): Promise<Server> {
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title} - video.folx.tv</title> <title>${title} | Folx TV - Video</title>
<meta name="description" content="${description}">
<meta name="keywords" content="${keywords}">
<!-- Open Graph meta tags for Facebook/Social Media -->
<meta property="og:type" content="video.other"> <meta property="og:type" content="video.other">
<meta property="og:title" content="${title}"> <meta property="og:title" content="${title}">
<meta property="og:description" content="${description}"> <meta property="og:description" content="${description}">
@ -171,21 +223,22 @@ export async function registerRoutes(app: Express): Promise<Server> {
<meta property="og:image:height" content="630"> <meta property="og:image:height" content="630">
<meta property="og:image:type" content="image/jpeg"> <meta property="og:image:type" content="image/jpeg">
<meta property="og:url" content="${videoUrl}"> <meta property="og:url" content="${videoUrl}">
<meta property="og:site_name" content="video.folx.tv"> <meta property="og:site_name" content="Folx TV - Video">
<meta property="og:locale" content="de_DE"> <meta property="og:locale" content="de_DE">
<!-- Twitter Card meta tags -->
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="${title}"> <meta name="twitter:title" content="${title}">
<meta name="twitter:description" content="${description}"> <meta name="twitter:description" content="${description}">
<meta name="twitter:image" content="${thumbnailUrl}"> <meta name="twitter:image" content="${thumbnailUrl}">
<link rel="canonical" href="${videoUrl}"> <link rel="canonical" href="${videoUrl}">
<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>
</head> </head>
<body> <body>
<h1>${title}</h1> <h1>${title}</h1>
${artistName ? `<h2>Interpret: ${artistName}</h2>` : ''}
<p>${description}</p> <p>${description}</p>
<p><a href="${videoUrl}">Watch on video.folx.tv</a></p> <p><a href="${videoUrl}">Jetzt ansehen auf Folx TV</a></p>
</body> </body>
</html>`; </html>`;
@ -291,8 +344,8 @@ export async function registerRoutes(app: Express): Promise<Server> {
const baseUrl = 'https://video.folx.tv'; const baseUrl = 'https://video.folx.tv';
const pageUrl = `${baseUrl}/player`; const pageUrl = `${baseUrl}/player`;
const title = 'Professional Player - video.folx.tv'; const title = 'Professional Player - Folx TV - Video';
const description = 'Professioneller Video Player mit MTV-Style Overlay Graphics und Streaming-Funktionen auf video.folx.tv'; const description = 'Professioneller Video Player mit Overlay Graphics und Streaming-Funktionen. Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.';
const imageUrl = `${baseUrl}/images/logo.svg`; const imageUrl = `${baseUrl}/images/logo.svg`;
const html = `<!DOCTYPE html> const html = `<!DOCTYPE html>
@ -348,8 +401,8 @@ export async function registerRoutes(app: Express): Promise<Server> {
const baseUrl = 'https://video.folx.tv'; const baseUrl = 'https://video.folx.tv';
const pageUrl = `${baseUrl}/live`; const pageUrl = `${baseUrl}/live`;
const title = 'LIVE Stream - video.folx.tv'; const title = 'LIVE Stream - Folx TV - Video';
const description = 'Live Stream auf video.folx.tv - Schauen Sie exklusive Inhalte in Echtzeit. FOLX TV Live Streaming rund um die Uhr.'; const description = 'Live Stream auf video.folx.tv - Schauen Sie exklusive Inhalte in Echtzeit. Folx TV - Nummer 1 in Europa für Volksmusik und Schlager.';
const imageUrl = `${baseUrl}/images/logo.svg`; const imageUrl = `${baseUrl}/images/logo.svg`;
const html = `<!DOCTYPE html> const html = `<!DOCTYPE html>
@ -386,6 +439,201 @@ export async function registerRoutes(app: Express): Promise<Server> {
res.send(html); res.send(html);
}); });
// Server-side meta tags for /folx-stadl page (crawlers + SEO)
app.get('/folx-stadl', async (req, res, next) => {
const userAgent = req.headers['user-agent']?.toLowerCase() || '';
const crawlers = [
'facebookexternalhit', 'facebot', 'twitterbot', 'whatsapp',
'telegrambot', 'linkedinbot', 'pinterest', 'slackbot',
'viberbot', 'discordbot', 'applebot', 'googlebot',
'bingbot', 'yandex', 'baiduspider', 'duckduckbot'
];
const isCrawler = crawlers.some(crawler => userAgent.includes(crawler));
if (!isCrawler) return next();
const baseUrl = 'https://video.folx.tv';
const pageUrl = `${baseUrl}/folx-stadl`;
const title = 'FOLX STADL - Die große Volksmusik Show | Folx TV - Video';
const description = 'FOLX STADL - Die beliebte Volksmusik- und Schlagershow auf Folx TV. Mit Stars wie Angela Wiedl, Oswald Sattler, Die Grubertaler, Kastelruther Spatzen und vielen mehr. Jetzt alle Folgen ansehen!';
const keywords = 'FOLX STADL, Volksmusik Show, Schlager, Angela Wiedl, Oswald Sattler, Die Grubertaler, Kastelruther Spatzen, Volksmusik TV, Folx TV';
const allVideos = await storage.getVideos(600, 0);
const stadlVideos = allVideos.filter(v => v.title.includes('FOLX STADL') || v.title.includes('FOLXSTADL'));
const html = `<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
<meta name="description" content="${description}">
<meta name="keywords" content="${keywords}">
<meta property="og:type" content="video.tv_show">
<meta property="og:title" content="${title}">
<meta property="og:description" content="${description}">
<meta property="og:url" content="${pageUrl}">
<meta property="og:site_name" content="video.folx.tv">
<meta property="og:locale" content="de_DE">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="${title}">
<meta name="twitter:description" content="${description}">
<link rel="canonical" href="${pageUrl}">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TVSeries",
"name": "FOLX STADL",
"description": "${description}",
"url": "${pageUrl}",
"numberOfEpisodes": ${stadlVideos.length},
"genre": ["Volksmusik", "Schlager", "Unterhaltung"],
"inLanguage": "de",
"productionCompany": {"@type": "Organization", "name": "FOLX.TV"},
"publisher": {"@type": "Organization", "name": "FOLX.TV", "url": "https://folx.tv"}
}
</script>
</head>
<body>
<h1>${title}</h1>
<p>${description}</p>
<h2>Alle FOLX STADL Folgen (${stadlVideos.length} Videos)</h2>
<ul>${stadlVideos.map(v => `<li><a href="${baseUrl}/video/${v.id.replace(/-/g, '').substring(0, 8)}">${v.title}</a></li>`).join('')}</ul>
</body>
</html>`;
res.set('Content-Type', 'text/html');
res.send(html);
});
// Server-side meta tags for /geschichte-lied page (crawlers + SEO)
app.get('/geschichte-lied', async (req, res, next) => {
const userAgent = req.headers['user-agent']?.toLowerCase() || '';
const crawlers = [
'facebookexternalhit', 'facebot', 'twitterbot', 'whatsapp',
'telegrambot', 'linkedinbot', 'pinterest', 'slackbot',
'viberbot', 'discordbot', 'applebot', 'googlebot',
'bingbot', 'yandex', 'baiduspider', 'duckduckbot'
];
const isCrawler = crawlers.some(crawler => userAgent.includes(crawler));
if (!isCrawler) return next();
const baseUrl = 'https://video.folx.tv';
const pageUrl = `${baseUrl}/geschichte-lied`;
const title = 'Die Geschichte des Liedes - Musikdokumentation | Folx TV - Video';
const description = 'Die Geschichte des Liedes - Entdecken Sie die Entstehung und Hintergründe der beliebtesten Volksmusik- und Schlagerlieder. Eine einzigartige Musikdokumentation auf Folx TV.';
const keywords = 'Geschichte des Liedes, Musikdokumentation, Volksmusik Geschichte, Schlager Historie, Liedgeschichte, Folx TV, Musiksendung';
const allVideos = await storage.getVideos(600, 0);
const geschichteVideos = allVideos.filter(v => v.title.includes('Geschichte des Liedes'));
const html = `<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
<meta name="description" content="${description}">
<meta name="keywords" content="${keywords}">
<meta property="og:type" content="video.tv_show">
<meta property="og:title" content="${title}">
<meta property="og:description" content="${description}">
<meta property="og:url" content="${pageUrl}">
<meta property="og:site_name" content="video.folx.tv">
<meta property="og:locale" content="de_DE">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="${title}">
<meta name="twitter:description" content="${description}">
<link rel="canonical" href="${pageUrl}">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TVSeries",
"name": "Die Geschichte des Liedes",
"description": "${description}",
"url": "${pageUrl}",
"numberOfEpisodes": ${geschichteVideos.length},
"genre": ["Musikdokumentation", "Volksmusik", "Schlager"],
"inLanguage": "de",
"productionCompany": {"@type": "Organization", "name": "FOLX.TV"},
"publisher": {"@type": "Organization", "name": "FOLX.TV", "url": "https://folx.tv"}
}
</script>
</head>
<body>
<h1>${title}</h1>
<p>${description}</p>
<h2>Alle Folgen (${geschichteVideos.length} Videos)</h2>
<ul>${geschichteVideos.map(v => `<li><a href="${baseUrl}/video/${v.id.replace(/-/g, '').substring(0, 8)}">${v.title}</a></li>`).join('')}</ul>
</body>
</html>`;
res.set('Content-Type', 'text/html');
res.send(html);
});
// Server-side meta tags for /gipfelstammtisch page (crawlers + SEO)
app.get('/gipfelstammtisch', async (req, res, next) => {
const userAgent = req.headers['user-agent']?.toLowerCase() || '';
const crawlers = [
'facebookexternalhit', 'facebot', 'twitterbot', 'whatsapp',
'telegrambot', 'linkedinbot', 'pinterest', 'slackbot',
'viberbot', 'discordbot', 'applebot', 'googlebot',
'bingbot', 'yandex', 'baiduspider', 'duckduckbot'
];
const isCrawler = crawlers.some(crawler => userAgent.includes(crawler));
if (!isCrawler) return next();
const baseUrl = 'https://video.folx.tv';
const pageUrl = `${baseUrl}/gipfelstammtisch`;
const title = 'Gipfelstammtisch - Volksmusik Talkshow | Folx TV - Video';
const description = 'Gipfelstammtisch - Die gemütliche Volksmusik-Talkshow auf Folx TV. Gespräche mit Stars der Volksmusik- und Schlagerszene in einzigartiger Alpenatmosphäre. Jetzt alle Folgen ansehen!';
const keywords = 'Gipfelstammtisch, Volksmusik Talkshow, Schlager Talk, Alpen, Volksmusik Stars, Folx TV, Musiksendung';
const allVideos = await storage.getVideos(600, 0);
const gipfelVideos = allVideos.filter(v => v.title.toLowerCase().includes('gipfelstammtisch'));
const html = `<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
<meta name="description" content="${description}">
<meta name="keywords" content="${keywords}">
<meta property="og:type" content="video.tv_show">
<meta property="og:title" content="${title}">
<meta property="og:description" content="${description}">
<meta property="og:url" content="${pageUrl}">
<meta property="og:site_name" content="video.folx.tv">
<meta property="og:locale" content="de_DE">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="${title}">
<meta name="twitter:description" content="${description}">
<link rel="canonical" href="${pageUrl}">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TVSeries",
"name": "Gipfelstammtisch",
"description": "${description}",
"url": "${pageUrl}",
"numberOfEpisodes": ${gipfelVideos.length},
"genre": ["Talkshow", "Volksmusik", "Unterhaltung"],
"inLanguage": "de",
"productionCompany": {"@type": "Organization", "name": "FOLX.TV"},
"publisher": {"@type": "Organization", "name": "FOLX.TV", "url": "https://folx.tv"}
}
</script>
</head>
<body>
<h1>${title}</h1>
<p>${description}</p>
<h2>Alle Folgen (${gipfelVideos.length} Videos)</h2>
<ul>${gipfelVideos.map(v => `<li><a href="${baseUrl}/video/${v.id.replace(/-/g, '').substring(0, 8)}">${v.title}</a></li>`).join('')}</ul>
</body>
</html>`;
res.set('Content-Type', 'text/html');
res.send(html);
});
// Sitemap.xml for SEO // Sitemap.xml for SEO
app.get("/sitemap.xml", async (req, res) => { app.get("/sitemap.xml", async (req, res) => {
try { try {
@ -411,16 +659,6 @@ export async function registerRoutes(app: Express): Promise<Server> {
<changefreq>daily</changefreq> <changefreq>daily</changefreq>
<priority>1.0</priority> <priority>1.0</priority>
</url> </url>
<url>
<loc>${baseUrl}/live</loc>
<changefreq>always</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>${baseUrl}/player</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url> <url>
<loc>${baseUrl}/folx-stadl</loc> <loc>${baseUrl}/folx-stadl</loc>
<changefreq>weekly</changefreq> <changefreq>weekly</changefreq>
@ -442,9 +680,26 @@ export async function registerRoutes(app: Express): Promise<Server> {
const shortId = video.id.replace(/-/g, '').substring(0, 8); const shortId = video.id.replace(/-/g, '').substring(0, 8);
const lastmod = video.createdAt ? new Date(video.createdAt).toISOString().split('T')[0] : new Date().toISOString().split('T')[0]; const lastmod = video.createdAt ? new Date(video.createdAt).toISOString().split('T')[0] : new Date().toISOString().split('T')[0];
const safeTitle = escapeXml(video.title); const safeTitle = escapeXml(video.title);
const safeDescription = escapeXml(video.description || video.title);
const safeThumbnail = escapeXml(video.thumbnailUrl || ''); const safeThumbnail = escapeXml(video.thumbnailUrl || '');
// Extract artist for richer description
const titleStr = video.title || '';
let artist = '';
let song = titleStr;
if (titleStr.includes('')) {
artist = titleStr.split('')[0].trim();
song = titleStr.split('').slice(1).join('').trim();
} else if (titleStr.includes(' - ')) {
artist = titleStr.split(' - ')[0].trim();
song = titleStr.split(' - ').slice(1).join(' - ').trim();
}
const safeDescription = escapeXml(
video.description ||
(artist ? `${artist} ${song}. Volksmusik und Schlager auf Folx TV - Nummer 1 in Europa.` : `${titleStr} auf Folx TV ansehen.`)
);
const safeTags = artist ? `<video:tag>${escapeXml(artist)}</video:tag><video:tag>Volksmusik</video:tag><video:tag>Schlager</video:tag><video:tag>Folx TV</video:tag>` : '<video:tag>Volksmusik</video:tag><video:tag>Schlager</video:tag><video:tag>Folx TV</video:tag>';
xml += ` <url> xml += ` <url>
<loc>${baseUrl}/video/${shortId}</loc> <loc>${baseUrl}/video/${shortId}</loc>
<lastmod>${lastmod}</lastmod> <lastmod>${lastmod}</lastmod>
@ -455,6 +710,8 @@ export async function registerRoutes(app: Express): Promise<Server> {
<video:title>${safeTitle}</video:title> <video:title>${safeTitle}</video:title>
<video:description>${safeDescription}</video:description> <video:description>${safeDescription}</video:description>
<video:duration>${video.duration || 0}</video:duration> <video:duration>${video.duration || 0}</video:duration>
<video:family_friendly>yes</video:family_friendly>
${safeTags}
</video:video> </video:video>
</url> </url>
`; `;