diff --git a/client/src/hooks/use-page-meta.ts b/client/src/hooks/use-page-meta.ts index 1c85749..8e20d6f 100644 --- a/client/src/hooks/use-page-meta.ts +++ b/client/src/hooks/use-page-meta.ts @@ -1,17 +1,69 @@ import { useEffect } from "react"; -export function usePageMeta(title: string, description?: string) { +interface OgMeta { + ogTitle?: string; + ogDescription?: string; + ogImage?: string; + ogType?: string; + ogUrl?: string; +} + +function setMetaTag(selector: string, content: string) { + let el = document.querySelector(selector) as HTMLMetaElement; + if (el) { + el.content = content; + } else { + el = document.createElement("meta"); + const [attr, value] = selector.match(/\[(.+?)="(.+?)"\]/)?.slice(1) || []; + if (attr && value) { + el.setAttribute(attr, value); + el.content = content; + document.head.appendChild(el); + } + } +} + +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_OG_IMAGE = "https://folx.tv/og-image.jpg"; + +export function usePageMeta(title: string, description?: string, og?: OgMeta) { useEffect(() => { const suffix = " | Folx Music Television"; document.title = title + suffix; if (description) { - let meta = document.querySelector('meta[name="description"]') as HTMLMetaElement; - if (meta) meta.content = description; + setMetaTag('meta[name="description"]', description); + } + if (og) { + if (og.ogTitle) setMetaTag('meta[property="og:title"]', og.ogTitle); + if (og.ogDescription) setMetaTag('meta[property="og:description"]', og.ogDescription); + if (og.ogImage) { + setMetaTag('meta[property="og:image"]', og.ogImage); + setMetaTag('meta[property="og:image:secure_url"]', og.ogImage); + 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('link[rel="canonical"]', og.ogUrl); + } + setMetaTag('meta[name="twitter:title"]', og.ogTitle || title + suffix); + setMetaTag('meta[name="twitter:description"]', og.ogDescription || description || DEFAULT_OG_DESC); } return () => { - document.title = "Volksmusik & Schlager | Folx Music Television"; - let meta = document.querySelector('meta[name="description"]') as HTMLMetaElement; - if (meta) meta.content = "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!"; + document.title = DEFAULT_TITLE; + setMetaTag('meta[name="description"]', DEFAULT_DESC); + setMetaTag('meta[property="og:title"]', DEFAULT_OG_TITLE); + setMetaTag('meta[property="og:description"]', DEFAULT_OG_DESC); + setMetaTag('meta[property="og:image"]', DEFAULT_OG_IMAGE); + setMetaTag('meta[property="og:image:secure_url"]', DEFAULT_OG_IMAGE); + setMetaTag('meta[name="twitter:title"]', DEFAULT_OG_TITLE); + setMetaTag('meta[name="twitter:description"]', DEFAULT_OG_DESC); + setMetaTag('meta[name="twitter:image"]', DEFAULT_OG_IMAGE); + setMetaTag('meta[property="og:type"]', "website"); + setMetaTag('meta[property="og:url"]', "https://folx.tv/"); }; - }, [title, description]); + }, [title, description, og?.ogTitle, og?.ogDescription, og?.ogImage, og?.ogType, og?.ogUrl]); } diff --git a/client/src/pages/article.tsx b/client/src/pages/article.tsx index ce97661..d106db0 100644 --- a/client/src/pages/article.tsx +++ b/client/src/pages/article.tsx @@ -101,11 +101,67 @@ export default function ArticlePage() { queryKey: ["/api/articles", slug], }); + const articleUrl = article ? `${window.location.origin}/article/${article.slug}` : ""; + const articleImage = article?.coverImage + ? (article.coverImage.startsWith("http") ? article.coverImage : `${window.location.origin}${article.coverImage}`) + : ""; + usePageMeta( article ? `${article.title} - Volksmusik & Schlager` : "Volksmusik & Schlager Artikel", - article?.excerpt || "Aktuelle Nachrichten aus der Volksmusik- und Schlagerszene bei FOLX TV." + article?.excerpt || "Aktuelle Nachrichten aus der Volksmusik- und Schlagerszene bei FOLX TV.", + article ? { + ogTitle: article.title, + ogDescription: article.excerpt, + ogImage: articleImage || undefined, + ogType: "article", + ogUrl: articleUrl, + } : undefined ); + useEffect(() => { + if (!article) return; + const jsonLd = { + "@context": "https://schema.org", + "@type": "NewsArticle", + "headline": article.title, + "description": article.excerpt, + "image": articleImage ? [articleImage] : [], + "datePublished": new Date(article.publishedAt).toISOString(), + "dateModified": new Date(article.publishedAt).toISOString(), + "author": { + "@type": "Organization", + "name": article.author || "Folx Music Television", + "url": "https://folx.tv" + }, + "publisher": { + "@type": "Organization", + "name": "Folx Music Television", + "url": "https://folx.tv", + "logo": { + "@type": "ImageObject", + "url": `${window.location.origin}/favicon.png` + } + }, + "mainEntityOfPage": { + "@type": "WebPage", + "@id": articleUrl + }, + "articleSection": article.category || "News", + "inLanguage": "de" + }; + const script = document.createElement("script"); + script.type = "application/ld+json"; + script.id = "article-jsonld"; + script.textContent = JSON.stringify(jsonLd); + const existing = document.getElementById("article-jsonld"); + if (existing) existing.remove(); + document.head.appendChild(script); + return () => { + const el = document.getElementById("article-jsonld"); + if (el) el.remove(); + }; + }, [article, articleUrl, articleImage]); + useEffect(() => { window.scrollTo(0, 0); }, [slug]); diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx index 8a18939..d5727d2 100644 --- a/client/src/pages/home.tsx +++ b/client/src/pages/home.tsx @@ -511,6 +511,39 @@ function BentoSkeleton() { export default function Home() { usePageMeta("Volksmusik & Schlager", "FOLX TV – Aktuelle Nachrichten, Musikvideos und Interviews aus der Welt der Volksmusik und des Schlagers."); + + useEffect(() => { + const jsonLd = { + "@context": "https://schema.org", + "@type": "WebSite", + "name": "Folx Music Television", + "alternateName": "FOLX TV", + "url": "https://folx.tv", + "description": "FOLX TV – Aktuelle Nachrichten, Musikvideos und Interviews aus der Welt der Volksmusik und des Schlagers.", + "publisher": { + "@type": "Organization", + "name": "Folx Music Television", + "url": "https://folx.tv", + "logo": { + "@type": "ImageObject", + "url": `${window.location.origin}/favicon.png` + } + }, + "inLanguage": "de" + }; + const script = document.createElement("script"); + script.type = "application/ld+json"; + script.id = "home-jsonld"; + script.textContent = JSON.stringify(jsonLd); + const existing = document.getElementById("home-jsonld"); + if (existing) existing.remove(); + document.head.appendChild(script); + return () => { + const el = document.getElementById("home-jsonld"); + if (el) el.remove(); + }; + }, []); + const { data: articles, isLoading } = useQuery({ queryKey: ["/api/articles"], });