import React from 'react' import Link from 'next/link' import SeoNavbar from '@/components/seo/SeoNavbar' import SeoFooter from '@/components/seo/SeoFooter' import { BlogPost } from '@/lib/blogPosts' const SITE = 'https://greenlenspro.com' /** * JSON-LD für Blogposts. BlogPosting liefert Autor und Datum, FAQPage und HowTo * sind die beiden Formate, aus denen AI-Antwortsysteme direkt extrahieren. * Ohne diese Blöcke bleibt der Beitrag für sie unstrukturierter Fließtext. */ function buildBlogSchema(post: BlogPost) { const graph: Record[] = [ { '@type': 'BlogPosting', '@id': `${SITE}${post.canonical}#article`, headline: post.title, description: post.metaDescription, image: `${SITE}${post.heroImage}`, datePublished: post.publishedAtIso, dateModified: post.updatedAtIso || post.publishedAtIso, inLanguage: post.locale, mainEntityOfPage: { '@type': 'WebPage', '@id': `${SITE}${post.canonical}` }, author: { '@type': 'Person', name: post.author.name, jobTitle: post.author.role, }, publisher: { '@type': 'Organization', name: 'GreenLens', url: SITE, }, ...(post.sources?.length ? { citation: post.sources.map((source) => ({ '@type': 'CreativeWork', name: source.title, url: source.url })) } : {}), }, ] if (post.faqs?.length) { graph.push({ '@type': 'FAQPage', '@id': `${SITE}${post.canonical}#faq`, mainEntity: post.faqs.map((faq) => ({ '@type': 'Question', name: faq.question, acceptedAnswer: { '@type': 'Answer', text: faq.answer }, })), }) } if (post.howToSteps?.length) { graph.push({ '@type': 'HowTo', '@id': `${SITE}${post.canonical}#howto`, name: post.howToName || post.title, step: post.howToSteps.map((step, index) => ({ '@type': 'HowToStep', position: index + 1, name: step.name.replace(/^\d+\.\s*/, ''), text: step.text, })), }) } return { '@context': 'https://schema.org', '@graph': graph } } function renderFormattedText(text: string) { if (!text) return null const regex = /\[([^\]]+)\]\(([^)]+)\)/g const parts: React.ReactNode[] = [] let lastIndex = 0 let match: RegExpExecArray | null while ((match = regex.exec(text)) !== null) { if (match.index > lastIndex) { parts.push(text.substring(lastIndex, match.index)) } const linkText = match[1] const url = match[2] const isExternal = url.startsWith('http') if (isExternal) { parts.push( {linkText} ) } else { parts.push( {linkText} ) } lastIndex = regex.lastIndex } if (lastIndex < text.length) { parts.push(text.substring(lastIndex)) } return parts.length > 0 ? parts : text } export function BlogPostTemplate({ post }: { post: BlogPost }) { return (