diff --git a/attached_assets/image_1772898100931.png b/attached_assets/image_1772898100931.png new file mode 100644 index 0000000..6b83a3d Binary files /dev/null and b/attached_assets/image_1772898100931.png differ diff --git a/client/index.html b/client/index.html index 6220880..28f8123 100644 --- a/client/index.html +++ b/client/index.html @@ -3,11 +3,11 @@ - Volksmusik & Schlager | Folx Music Television - - - - + Volksmusik & Schlager TV | FOLX Music Television – Nachrichten, Videos & mehr + + + + @@ -19,8 +19,8 @@ - - + + diff --git a/client/src/components/footer.tsx b/client/src/components/footer.tsx index f67180c..2d70d29 100644 --- a/client/src/components/footer.tsx +++ b/client/src/components/footer.tsx @@ -16,8 +16,8 @@ export default function Footer() {

Folx Music Television

- Folx Music Television. Aktuelle Nachrichten, Interviews und - Hintergrundberichte aus der Welt der Volksmusik und des Schlagers. + FOLX TV – Ihr Fernsehsender Nr. 1 für Volksmusik und Schlager. Aktuelle Nachrichten, + Musikvideos, Künstlerporträts, Live-Shows und Interviews aus der Welt der volkstümlichen Musik.

{SOCIAL_LINKS.map((s) => ( diff --git a/client/src/components/header.tsx b/client/src/components/header.tsx index d1429fb..699459f 100644 --- a/client/src/components/header.tsx +++ b/client/src/components/header.tsx @@ -45,7 +45,7 @@ export default function Header() {
- Folx TV + FOLX TV – Volksmusik & Schlager Fernsehsender
diff --git a/client/src/components/push-prompt-banner.tsx b/client/src/components/push-prompt-banner.tsx index 1abbd75..4aa50a0 100644 --- a/client/src/components/push-prompt-banner.tsx +++ b/client/src/components/push-prompt-banner.tsx @@ -49,8 +49,8 @@ export default function PushPromptBanner() { if (!visible) return null; return ( -
-
+
+
diff --git a/client/src/hooks/use-page-meta.ts b/client/src/hooks/use-page-meta.ts index ef1a399..2e64820 100644 --- a/client/src/hooks/use-page-meta.ts +++ b/client/src/hooks/use-page-meta.ts @@ -31,11 +31,24 @@ function removeMetaTag(selector: string) { if (el) el.remove(); } -const DEFAULT_TITLE = "Volksmusik & Schlager | Folx Music Television"; -const DEFAULT_DESC = "FOLX TV – Ihr Fernsehsender für Volksmusik und Schlager. Musikvideos, Live-Shows, Interviews und aktuelle Nachrichten aus der Welt der volkstümlichen Musik. Jetzt einschalten!"; -const DEFAULT_OG_TITLE = "Volksmusik & Schlager | Folx Music Television"; -const DEFAULT_OG_DESC = "FOLX TV – Ihr Fernsehsender für Volksmusik und Schlager. Musikvideos, Live-Shows und aktuelle Nachrichten aus der volkstümlichen Musikszene."; +const DEFAULT_TITLE = "Volksmusik & Schlager TV | FOLX Music Television – Nachrichten, Videos & mehr"; +const DEFAULT_DESC = "FOLX TV – Ihr Fernsehsender Nr. 1 für Volksmusik und Schlager. Aktuelle Nachrichten, Musikvideos, Künstlerporträts, Live-Shows und Interviews aus der Welt der volkstümlichen Musik. Jetzt einschalten!"; +const DEFAULT_OG_TITLE = "Volksmusik & Schlager TV | FOLX Music Television"; +const DEFAULT_OG_DESC = "FOLX TV – Ihr Fernsehsender Nr. 1 für Volksmusik und Schlager. Aktuelle Nachrichten, Musikvideos, Künstlerporträts und Live-Shows."; const DEFAULT_OG_IMAGE = "https://folx.tv/og-image.jpg"; +const CANONICAL_BASE = "https://folx.tv"; + +function setCanonical(href: string) { + let link = document.querySelector('link[rel="canonical"]') as HTMLLinkElement; + if (link) { + link.href = href; + } else { + link = document.createElement("link"); + link.rel = "canonical"; + link.href = href; + document.head.appendChild(link); + } +} export function usePageMeta(title: string, description?: string, og?: OgMeta) { useEffect(() => { @@ -44,6 +57,12 @@ export function usePageMeta(title: string, description?: string, og?: OgMeta) { if (description) { setMetaTag('meta[name="description"]', description); } + + const canonicalPath = og?.ogUrl || `${CANONICAL_BASE}${window.location.pathname}`; + const canonicalUrl = canonicalPath.startsWith("http") ? canonicalPath : `${CANONICAL_BASE}${canonicalPath}`; + setCanonical(canonicalUrl); + setMetaTag('meta[property="og:url"]', canonicalUrl); + if (og) { if (og.ogTitle) setMetaTag('meta[property="og:title"]', og.ogTitle); if (og.ogDescription) setMetaTag('meta[property="og:description"]', og.ogDescription); @@ -53,9 +72,6 @@ export function usePageMeta(title: string, description?: string, og?: OgMeta) { setMetaTag('meta[name="twitter:image"]', og.ogImage); } if (og.ogType) setMetaTag('meta[property="og:type"]', og.ogType); - if (og.ogUrl) { - setMetaTag('meta[property="og:url"]', og.ogUrl); - } setMetaTag('meta[name="twitter:title"]', og.ogTitle || title + suffix); setMetaTag('meta[name="twitter:description"]', og.ogDescription || description || DEFAULT_OG_DESC); @@ -82,6 +98,7 @@ export function usePageMeta(title: string, description?: string, og?: OgMeta) { setMetaTag('meta[name="twitter:image"]', DEFAULT_OG_IMAGE); setMetaTag('meta[property="og:type"]', "website"); setMetaTag('meta[property="og:url"]', "https://folx.tv/"); + setCanonical("https://folx.tv/"); removeMetaTag('meta[property="article:published_time"]'); removeMetaTag('meta[property="article:modified_time"]'); removeMetaTag('meta[property="article:author"]'); diff --git a/client/src/pages/about.tsx b/client/src/pages/about.tsx index 4a34cfe..51a0293 100644 --- a/client/src/pages/about.tsx +++ b/client/src/pages/about.tsx @@ -5,7 +5,7 @@ import { usePageMeta } from "@/hooks/use-page-meta"; import { PageSideAds } from "@/components/adsense"; export default function AboutPage() { - usePageMeta("Über FOLX TV - Volksmusik & Schlager Fernsehsender", "Alles über FOLX TV – Ihren Fernsehsender für Volksmusik und Schlager seit 2013."); + usePageMeta("Über FOLX TV - Volksmusik & Schlager Fernsehsender", "Alles über FOLX TV – Ihren Volksmusik & Schlager Fernsehsender seit 2013. Programm, Geschichte und das Team hinter dem Volksmusik-Sender."); return (
diff --git a/client/src/pages/article.tsx b/client/src/pages/article.tsx index 16daa4d..3e77ef9 100644 --- a/client/src/pages/article.tsx +++ b/client/src/pages/article.tsx @@ -150,12 +150,22 @@ export default function ArticlePage() { "@id": articleUrl }, "articleSection": article.category || "News", - "inLanguage": "de" + "inLanguage": "de", + "keywords": `Volksmusik, Schlager, ${article.category || "News"}, ${article.title}` + }; + const breadcrumbLd = { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + "itemListElement": [ + { "@type": "ListItem", "position": 1, "name": "FOLX TV", "item": "https://folx.tv" }, + { "@type": "ListItem", "position": 2, "name": article.category || "News", "item": `https://folx.tv/category/${encodeURIComponent(article.category || "News")}` }, + { "@type": "ListItem", "position": 3, "name": article.title, "item": articleUrl } + ] }; const script = document.createElement("script"); script.type = "application/ld+json"; script.id = "article-jsonld"; - script.textContent = JSON.stringify(jsonLd); + script.textContent = JSON.stringify([jsonLd, breadcrumbLd]); const existing = document.getElementById("article-jsonld"); if (existing) existing.remove(); document.head.appendChild(script); diff --git a/client/src/pages/category.tsx b/client/src/pages/category.tsx index b9b6ee4..f05495a 100644 --- a/client/src/pages/category.tsx +++ b/client/src/pages/category.tsx @@ -30,7 +30,7 @@ export default function CategoryPage() { usePageMeta( `${category}${currentPage > 1 ? ` – Seite ${currentPage}` : ""} - Volksmusik & Schlager`, - `Aktuelle ${category}-Beiträge aus der Volksmusik- und Schlagerszene bei FOLX TV.` + `Aktuelle ${category}-Beiträge und Nachrichten aus der Volksmusik- und Schlagerszene. Neueste Volksmusik-Meldungen bei FOLX TV.` ); const { data, isLoading } = useQuery({ diff --git a/client/src/pages/datenschutz.tsx b/client/src/pages/datenschutz.tsx index b58a2b7..1b8fed2 100644 --- a/client/src/pages/datenschutz.tsx +++ b/client/src/pages/datenschutz.tsx @@ -5,7 +5,7 @@ import { usePageMeta } from "@/hooks/use-page-meta"; import { PageSideAds } from "@/components/adsense"; export default function DatenschutzPage() { - usePageMeta("Datenschutz - FOLX TV", "Datenschutzerklärung von FOLX TV – Ihr Volksmusik & Schlager Fernsehsender."); + usePageMeta("Datenschutz - FOLX TV Volksmusik Sender", "Datenschutzerklärung von FOLX TV – Ihrem Volksmusik & Schlager Fernsehsender."); return (
diff --git a/client/src/pages/empfang.tsx b/client/src/pages/empfang.tsx index f3a157a..753dc9c 100644 --- a/client/src/pages/empfang.tsx +++ b/client/src/pages/empfang.tsx @@ -34,7 +34,7 @@ const COUNTRIES = [ ]; export default function EmpfangPage() { - usePageMeta("Empfang FOLX TV - Volksmusik & Schlager Sender empfangen", "So empfangen Sie FOLX TV – Ihren Volksmusik & Schlager Sender in Deutschland, Österreich und der Schweiz."); + usePageMeta("Empfang FOLX TV - Volksmusik & Schlager Sender empfangen", "So empfangen Sie FOLX TV – den Volksmusik & Schlager Sender in Deutschland, Österreich und der Schweiz. Kabel, Satellit und Streaming-Optionen."); return (
diff --git a/client/src/pages/gallery.tsx b/client/src/pages/gallery.tsx index 1ed3610..e619a70 100644 --- a/client/src/pages/gallery.tsx +++ b/client/src/pages/gallery.tsx @@ -7,7 +7,7 @@ import { usePageMeta } from "@/hooks/use-page-meta"; import { InArticleAd, PageSideAds } from "@/components/adsense"; export default function GalleryPageWrapper() { - usePageMeta("Fotogalerie - Volksmusik & Schlager Bilder", "Fotos und Bilder von Volksmusik- und Schlager-Stars bei FOLX TV."); + usePageMeta("Fotogalerie - Volksmusik & Schlager Bilder", "Exklusive Fotos und Bilder von Volksmusik- und Schlager-Stars, Konzerten und Events. Die Volksmusik-Fotogalerie von FOLX TV."); return (
diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx index 30bf383..4e24acd 100644 --- a/client/src/pages/home.tsx +++ b/client/src/pages/home.tsx @@ -511,16 +511,16 @@ function BentoSkeleton() { } export default function Home() { - usePageMeta("Volksmusik & Schlager", "FOLX TV – Aktuelle Nachrichten, Musikvideos und Interviews aus der Welt der Volksmusik und des Schlagers."); + usePageMeta("Volksmusik & Schlager TV", "FOLX TV – Ihr Fernsehsender Nr. 1 für Volksmusik und Schlager. Aktuelle Nachrichten, Musikvideos, Künstlerporträts, Live-Shows und Interviews aus der Welt der volkstümlichen Musik."); useEffect(() => { const jsonLd = { "@context": "https://schema.org", "@type": "WebSite", "name": "Folx Music Television", - "alternateName": "FOLX TV", + "alternateName": ["FOLX TV", "Volksmusik TV"], "url": "https://folx.tv", - "description": "FOLX TV – Aktuelle Nachrichten, Musikvideos und Interviews aus der Welt der Volksmusik und des Schlagers.", + "description": "FOLX TV – Ihr Fernsehsender Nr. 1 für Volksmusik und Schlager. Aktuelle Nachrichten, Musikvideos, Künstlerporträts, Live-Shows und Interviews aus der Welt der volkstümlichen Musik.", "publisher": { "@type": "Organization", "name": "Folx Music Television", @@ -528,7 +528,18 @@ export default function Home() { "logo": { "@type": "ImageObject", "url": `${window.location.origin}/favicon.png` - } + }, + "sameAs": [ + "https://www.facebook.com/folxtvmusic", + "https://www.instagram.com/folxtv", + "https://www.youtube.com/@FolxTV", + "https://www.tiktok.com/@folx.tv" + ] + }, + "potentialAction": { + "@type": "SearchAction", + "target": "https://folx.tv/search?q={search_term_string}", + "query-input": "required name=search_term_string" }, "inLanguage": "de" }; @@ -692,6 +703,7 @@ export default function Home() {
+

FOLX TV – Volksmusik & Schlager Fernsehsender: Nachrichten, Videos und Live-Shows

diff --git a/client/src/pages/horoscope.tsx b/client/src/pages/horoscope.tsx index b3063ec..edb2c21 100644 --- a/client/src/pages/horoscope.tsx +++ b/client/src/pages/horoscope.tsx @@ -369,7 +369,7 @@ function SignDetail({ signIndex, onNavigate, aiHoroscopes }: { signIndex: number } export default function HoroscopePage() { - usePageMeta("Horoskop - Volksmusik & Schlager", "Tägliches Horoskop für Volksmusik- und Schlager-Fans bei FOLX TV."); + usePageMeta("Horoskop - Volksmusik & Schlager", "Tägliches Horoskop für alle Sternzeichen. Ihr persönliches Tageshoroskop bei FOLX TV – dem Volksmusik & Schlager Sender."); const params = useParams<{ sign?: string }>(); const [selected, setSelected] = useState(null); const detailRef = useRef(null); diff --git a/client/src/pages/impressum.tsx b/client/src/pages/impressum.tsx index cd6f26a..1979ea3 100644 --- a/client/src/pages/impressum.tsx +++ b/client/src/pages/impressum.tsx @@ -5,7 +5,7 @@ import { usePageMeta } from "@/hooks/use-page-meta"; import { PageSideAds } from "@/components/adsense"; export default function ImpressumPage() { - usePageMeta("Impressum - FOLX TV", "Impressum und rechtliche Informationen zu FOLX TV – Volksmusik & Schlager Fernsehsender."); + usePageMeta("Impressum - FOLX TV Volksmusik Sender", "Impressum und rechtliche Informationen zu FOLX TV – Ihrem Volksmusik & Schlager Fernsehsender."); return (
diff --git a/client/src/pages/kontakt.tsx b/client/src/pages/kontakt.tsx index 3bbd404..5a475ef 100644 --- a/client/src/pages/kontakt.tsx +++ b/client/src/pages/kontakt.tsx @@ -8,7 +8,7 @@ import { PageSideAds } from "@/components/adsense"; import { apiRequest } from "@/lib/queryClient"; export default function KontaktPage() { - usePageMeta("Kontakt - FOLX TV", "Kontaktieren Sie FOLX TV – Ihr Fernsehsender für Volksmusik und Schlager."); + usePageMeta("Kontakt - FOLX TV Volksmusik Sender", "Kontaktieren Sie FOLX TV – Ihren Fernsehsender Nr. 1 für Volksmusik und Schlager. Wir freuen uns auf Ihre Nachricht."); const [formData, setFormData] = useState({ name: "", email: "", subject: "", message: "" }); const [status, setStatus] = useState<"idle" | "sending" | "success" | "error">("idle"); diff --git a/client/src/pages/recipes.tsx b/client/src/pages/recipes.tsx index 0c461d6..6abdccd 100644 --- a/client/src/pages/recipes.tsx +++ b/client/src/pages/recipes.tsx @@ -296,7 +296,7 @@ function RecipeModal({ recipe, onClose }: { recipe: Recipe; onClose: () => void } export default function RecipesPage() { - usePageMeta("Rezepte - Alpenküche & Schlager", "Traditionelle Rezepte aus der Alpenküche bei FOLX TV – kochen wie die Volksmusik-Stars."); + usePageMeta("Rezepte - Alpenküche & Volksmusik", "Traditionelle Rezepte aus der Alpenküche und österreichische Hausmannskost. Kochen wie die Volksmusik-Stars bei FOLX TV."); const [selectedRecipe, setSelectedRecipe] = useState(null); return ( diff --git a/client/src/pages/search.tsx b/client/src/pages/search.tsx index f9236db..066f22a 100644 --- a/client/src/pages/search.tsx +++ b/client/src/pages/search.tsx @@ -27,7 +27,7 @@ interface SearchResult { } export default function SearchPage() { - usePageMeta("Suche - Volksmusik & Schlager", "Durchsuchen Sie FOLX TV nach Volksmusik- und Schlager-Inhalten."); + usePageMeta("Suche - Volksmusik & Schlager", "Durchsuchen Sie FOLX TV nach Volksmusik- und Schlager-Nachrichten, Künstlern, Videos und mehr."); const searchString = useSearch(); const initialQuery = new URLSearchParams(searchString).get("q") || ""; const [query, setQuery] = useState(initialQuery); diff --git a/client/src/pages/videos.tsx b/client/src/pages/videos.tsx index 69ce30b..faea7d3 100644 --- a/client/src/pages/videos.tsx +++ b/client/src/pages/videos.tsx @@ -72,7 +72,7 @@ function VideoCardSkeleton() { } export default function VideosPage() { - usePageMeta("Volksmusik & Schlager Videos", "Musikvideos und Live-Auftritte aus der Volksmusik- und Schlagerszene bei FOLX TV."); + usePageMeta("Volksmusik & Schlager Videos", "Volksmusik und Schlager Musikvideos, Live-Auftritte und Konzertmitschnitte bei FOLX TV. Die besten volkstümlichen Hits und Schlager-Stars im Video."); const searchString = useSearch(); const [, setLocation] = useLocation(); diff --git a/replit.md b/replit.md index 877042a..feefcfe 100644 --- a/replit.md +++ b/replit.md @@ -3,6 +3,17 @@ ## Overview The official website for Folx Music Television (folx.tv). Dark-themed bento grid layout with content for folk music (Volksmusik/Schlager) fans. Features articles, videos, photo gallery, horoscope widget + subpage, recipe widget + subpage, Google News feed, and integrated AdSense ads. All content is hardcoded in seed for production deployments. +## SEO +- Primary keyword: "Volksmusik" — used across all page titles, meta descriptions, OG tags, and structured data +- Dynamic canonical URLs via `usePageMeta` hook (updates `` per page) +- SSR article pages: server-side meta tags (OG, Twitter, description, keywords, canonical) in both `server/vite.ts` (dev) and `server/static.ts` (prod) +- `stripExistingMeta()` removes duplicate meta/canonical from base HTML before injecting article-specific ones +- JSON-LD structured data: WebSite (home) with SearchAction, NewsArticle + BreadcrumbList (articles) +- Sitemap at `/sitemap.xml` — includes all static pages, categories, horoscope signs, and articles +- robots.txt disallows `/api/`, `/search`, `/admin/` +- H1 tag on home page (sr-only): "FOLX TV – Volksmusik & Schlager Fernsehsender" +- Logo alt text includes "Volksmusik & Schlager Fernsehsender" + ## Architecture - **Frontend**: React + Vite + TailwindCSS + shadcn/ui (dark mode) - **Backend**: Express.js + Node.js diff --git a/server/routes.ts b/server/routes.ts index 01efb6b..b10b9b6 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -821,6 +821,7 @@ export async function registerRoutes( { loc: "/gallery", priority: "0.7", changefreq: "weekly" }, { loc: "/horoskop", priority: "0.7", changefreq: "daily" }, { loc: "/rezepte", priority: "0.6", changefreq: "monthly" }, + { loc: "/kontakt", priority: "0.5", changefreq: "yearly" }, { loc: "/empfang-folx-tv", priority: "0.5", changefreq: "monthly" }, { loc: "/ueber-uns", priority: "0.4", changefreq: "yearly" }, { loc: "/impressum", priority: "0.3", changefreq: "yearly" }, @@ -888,6 +889,7 @@ export async function registerRoutes( Allow: / Disallow: /api/ Disallow: /search +Disallow: /admin/ Sitemap: https://folx.tv/sitemap.xml `; diff --git a/server/static.ts b/server/static.ts index 91020dc..e604337 100644 --- a/server/static.ts +++ b/server/static.ts @@ -21,6 +21,7 @@ function stripExistingMeta(html: string): string { html = html.replace(/]*>\s*/gi, ""); html = html.replace(/]*>\s*/gi, ""); html = html.replace(/]*>\s*/gi, ""); + html = html.replace(/]*>\s*/gi, ""); return html; } @@ -80,7 +81,9 @@ export function serveStatic(app: Express) { ``, ``, ``, - `${escapeHtml(article.title)} - Folx Music Television`, + ``, + ``, + `${escapeHtml(article.title)} - Volksmusik & Schlager | Folx Music Television`, ].join("\n "); template = template.replace(/[^<]*<\/title>/, ogTags); diff --git a/server/vite.ts b/server/vite.ts index b5e6009..9725476 100644 --- a/server/vite.ts +++ b/server/vite.ts @@ -27,6 +27,7 @@ function stripExistingMeta(html: string): string { html = html.replace(/<meta\s+name="twitter:[^"]*"[^>]*>\s*/gi, ""); html = html.replace(/<meta\s+name="description"[^>]*>\s*/gi, ""); html = html.replace(/<meta\s+name="keywords"[^>]*>\s*/gi, ""); + html = html.replace(/<link\s+rel="canonical"[^>]*>\s*/gi, ""); return html; } @@ -101,7 +102,9 @@ export async function setupVite(server: Server, app: Express) { `<meta name="twitter:description" content="${escapeHtml(article.excerpt)}" />`, `<meta name="twitter:image" content="${escapeHtml(finalImage)}" />`, `<meta name="description" content="${escapeHtml(article.excerpt)}" />`, - `<title>${escapeHtml(article.title)} - Folx Music Television`, + ``, + ``, + `${escapeHtml(article.title)} - Volksmusik & Schlager | Folx Music Television`, ].join("\n "); template = template.replace(/[^<]*<\/title>/, ogTags);