From 590584b893b34e5410a98db810cdc382103b1da4 Mon Sep 17 00:00:00 2001
From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com>
Date: Fri, 13 Feb 2026 17:53:37 +0000
Subject: [PATCH] Add an artist listing page and improve SEO for various pages
Introduces a new `/kuenstler` page, API endpoint `/api/artists`, and enhances meta tags on `index.html` and for crawler requests on `/kuenstler`. Adds `KuenstlerPage.tsx` and updates `routes.ts` and `index.html`.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 401e2ec0-e00d-4f10-9d0e-60f3d479f9a5
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: 69ee4fdb-c617-4cdd-b9f6-d3fab268d533
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/401e2ec0-e00d-4f10-9d0e-60f3d479f9a5/qFrskyV
---
client/index.html | 1 +
client/src/App.tsx | 2 +
client/src/pages/KuenstlerPage.tsx | 162 +++++++++++++++++++++++++++++
client/src/pages/home.tsx | 7 ++
server/routes.ts | 134 +++++++++++++++++++++++-
5 files changed, 304 insertions(+), 2 deletions(-)
create mode 100644 client/src/pages/KuenstlerPage.tsx
diff --git a/client/index.html b/client/index.html
index 5be0427..03db3e7 100644
--- a/client/index.html
+++ b/client/index.html
@@ -19,6 +19,7 @@
+
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 45c9944..c4ff039 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -11,6 +11,7 @@ import GeschichteLiedPage from "@/pages/GeschichteLiedPage";
import GipfelstammtischPage from "@/pages/GipfelstammtischPage";
import LivePage from "@/pages/LivePage";
import PlayerPage from "@/pages/PlayerPage";
+import KuenstlerPage from "@/pages/KuenstlerPage";
import AdminPage from "@/pages/admin";
import PrivacyPolicy from "@/pages/PrivacyPolicy";
import TermsOfService from "@/pages/TermsOfService";
@@ -27,6 +28,7 @@ function Router() {
+
diff --git a/client/src/pages/KuenstlerPage.tsx b/client/src/pages/KuenstlerPage.tsx
new file mode 100644
index 0000000..78835f6
--- /dev/null
+++ b/client/src/pages/KuenstlerPage.tsx
@@ -0,0 +1,162 @@
+import { useQuery } from '@tanstack/react-query';
+import { Link, useLocation } from 'wouter';
+import { ArrowLeft, Music, Users, Search, Menu, X } from 'lucide-react';
+import { useState, useEffect } from 'react';
+import HeaderAd from '@/components/HeaderAd';
+
+interface Artist {
+ name: string;
+ videoCount: number;
+}
+
+export default function KuenstlerPage() {
+ const [searchQuery, setSearchQuery] = useState("");
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
+ const [, setLocation] = useLocation();
+
+ useEffect(() => {
+ document.title = 'Alle Künstler & Interpreten | Folx TV - Video';
+ const metaDescription = document.querySelector('meta[name="description"]');
+ if (metaDescription) {
+ metaDescription.setAttribute('content', 'Entdecken Sie alle Volksmusik- und Schlager-Künstler auf Folx TV. Nummer 1 in Europa für Volksmusik und Schlager.');
+ }
+ }, []);
+
+ const { data, isLoading } = useQuery<{ artists: Artist[], total: number }>({
+ queryKey: ['/api/artists'],
+ });
+
+ const artists = data?.artists || [];
+ const filteredArtists = searchQuery
+ ? artists.filter(a => a.name.toLowerCase().includes(searchQuery.toLowerCase()))
+ : artists;
+
+ const letters = Array.from(new Set(filteredArtists.map(a => a.name.charAt(0).toUpperCase()))).sort((a, b) => a.localeCompare(b, 'de'));
+
+ if (isLoading) {
+ return (
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+ Folx TV
+
+
+
+
+
+
+
+
+
+ {isMobileMenuOpen && (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
Alle Künstler & Interpreten
+
+ {artists.length} Künstler
+
+
+
+
+
+ setSearchQuery(e.target.value)}
+ className="w-full pl-10 pr-4 py-3 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-purple-500"
+ />
+
+
+
+
+ {letters.map(letter => {
+ const letterArtists = filteredArtists.filter(a => a.name.charAt(0).toUpperCase() === letter);
+ return (
+
+
{letter}
+
+ {letterArtists.map(artist => (
+
+
+
+
+
+
{artist.name}
+
{artist.videoCount} Video{artist.videoCount > 1 ? 's' : ''}
+
+
+ ))}
+
+
+ );
+ })}
+
+ {filteredArtists.length === 0 && (
+
+
+
Keine Künstler gefunden für "{searchQuery}"
+
+ )}
+
+
+
+
+ );
+}
diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx
index f83e56c..4bfd6a6 100644
--- a/client/src/pages/home.tsx
+++ b/client/src/pages/home.tsx
@@ -56,6 +56,13 @@ export default function Home() {
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.');
}
+ let metaKeywords = document.querySelector('meta[name="keywords"]');
+ if (!metaKeywords) {
+ metaKeywords = document.createElement('meta');
+ metaKeywords.setAttribute('name', 'keywords');
+ document.head.appendChild(metaKeywords);
+ }
+ metaKeywords.setAttribute('content', 'Volksmusik, Schlager, Folx TV, Kastelruther Spatzen, Monika Martin, Oswald Sattler, Angela Wiedl, Die Grubertaler, Michael Hirte, Sašo Avsenik, Jonny Hill, Rosanna Rocci, Linda Feller, Julia Buchner, Melanie Payer, Marlena Martinelli, Musikvideo, Streaming');
}, []);
// Update videos when new data comes in
diff --git a/server/routes.ts b/server/routes.ts
index e805085..7eaa3e7 100644
--- a/server/routes.ts
+++ b/server/routes.ts
@@ -20,6 +20,30 @@ import { setupAuth, isAuthenticated, isAdmin } from "./replitAuth";
import { ObjectStorageService, ObjectNotFoundError } from "./objectStorage";
import { generateVideoDescription, generateBulkDescriptions } from "./aiService";
+// Extract unique artist names from video titles
+function extractArtists(videos: any[]): { name: string; videoCount: number; videos: any[] }[] {
+ const artistMap = new Map();
+ for (const v of videos) {
+ const title = v.title || '';
+ let artist = '';
+ if (title.includes('–')) {
+ artist = title.split('–')[0].trim();
+ } else if (title.includes(' - ')) {
+ artist = title.split(' - ')[0].trim();
+ }
+ if (artist && !artist.toUpperCase().startsWith('FOLX')) {
+ const normalized = artist.replace(/\s+/g, ' ').trim();
+ if (!artistMap.has(normalized)) {
+ artistMap.set(normalized, []);
+ }
+ artistMap.get(normalized)!.push(v);
+ }
+ }
+ return Array.from(artistMap.entries())
+ .map(([name, vids]) => ({ name, videoCount: vids.length, videos: vids }))
+ .sort((a, b) => a.name.localeCompare(b.name, 'de'));
+}
+
// Find video by short or long ID - moved to top level for export
export async function findVideoByAnyId(id: string) {
try {
@@ -439,6 +463,95 @@ export async function registerRoutes(app: Express): Promise {
res.send(html);
});
+ // API endpoint for artists list
+ app.get('/api/artists', async (req, res) => {
+ try {
+ const allVideos = await storage.getVideos(600, 0);
+ const artists = extractArtists(allVideos);
+ res.json({ artists: artists.map(a => ({ name: a.name, videoCount: a.videoCount })), total: artists.length });
+ } catch (error) {
+ res.status(500).json({ message: 'Error fetching artists' });
+ }
+ });
+
+ // Server-side meta tags for /kuenstler page (crawlers + SEO)
+ app.get('/kuenstler', 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}/kuenstler`;
+ const allVideos = await storage.getVideos(600, 0);
+ const artists = extractArtists(allVideos);
+ const topArtists = artists.slice(0, 30).map(a => a.name).join(', ');
+ const title = `Alle Künstler & Interpreten (${artists.length}) | Folx TV - Video`;
+ const description = `Entdecken Sie ${artists.length} Volksmusik- und Schlager-Künstler auf Folx TV: ${topArtists} und viele mehr. Nummer 1 in Europa für Volksmusik und Schlager.`;
+ const keywords = artists.map(a => a.name).join(', ') + ', Volksmusik, Schlager, Folx TV';
+
+ const escapeHtml = (s: string) => s.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
+
+ const jsonLd = {
+ "@context": "https://schema.org",
+ "@type": "CollectionPage",
+ "name": title,
+ "description": description,
+ "url": pageUrl,
+ "numberOfItems": artists.length,
+ "publisher": { "@type": "Organization", "name": "FOLX.TV", "url": "https://folx.tv" },
+ "inLanguage": "de",
+ "mainEntity": {
+ "@type": "ItemList",
+ "numberOfItems": artists.length,
+ "itemListElement": artists.map((a, i) => ({
+ "@type": "ListItem",
+ "position": i + 1,
+ "item": {
+ "@type": "MusicGroup",
+ "name": a.name,
+ "url": `${pageUrl}#letter-${a.name.charAt(0).toUpperCase()}`
+ }
+ }))
+ }
+ };
+
+ const html = `
+
+
+
+
+ ${escapeHtml(title)}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Alle Künstler & Interpreten auf Folx TV
+ ${escapeHtml(description)}
+ Insgesamt ${artists.length} Künstler mit ${allVideos.length} Musikvideos.
+ ${artists.map(a => `- ${escapeHtml(a.name)} (${a.videoCount} Video${a.videoCount > 1 ? 's' : ''})
`).join('')}
+
+`;
+ res.set('Content-Type', 'text/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() || '';
@@ -520,7 +633,7 @@ export async function registerRoutes(app: Express): Promise {
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 keywords = 'Geschichte des Liedes, Musikdokumentation, Volksmusik Geschichte, Schlager Historie, Liedgeschichte, Folx TV, Musiksendung, Kastelruther Spatzen, Monika Martin, Oswald Sattler, Angela Wiedl, Die Grubertaler';
const allVideos = await storage.getVideos(600, 0);
const geschichteVideos = allVideos.filter(v => v.title.includes('Geschichte des Liedes'));
@@ -585,7 +698,7 @@ export async function registerRoutes(app: Express): Promise {
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 keywords = 'Gipfelstammtisch, Volksmusik Talkshow, Schlager Talk, Alpen, Volksmusik Stars, Folx TV, Musiksendung, Kastelruther Spatzen, Monika Martin, Oswald Sattler, Angela Wiedl, Michael Hirte';
const allVideos = await storage.getVideos(600, 0);
const gipfelVideos = allVideos.filter(v => v.title.toLowerCase().includes('gipfelstammtisch'));
@@ -674,8 +787,25 @@ export async function registerRoutes(app: Express): Promise {
weekly
0.7
+
+ ${baseUrl}/kuenstler
+ weekly
+ 0.8
+
`;
+ // Add artist letter-index anchors to sitemap
+ const artists = extractArtists(videos);
+ const artistLetters = Array.from(new Set(artists.map(a => a.name.charAt(0).toUpperCase()))).sort();
+ for (const letter of artistLetters) {
+ xml += `
+ ${baseUrl}/kuenstler#letter-${escapeXml(letter)}
+ weekly
+ 0.6
+
+`;
+ }
+
for (const video of videos) {
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];