# SEO-Erweiterung *Letzte Aktualisierung: 18. Dezember 2025* ## Übersicht Diese Dokumentation beschreibt die implementierten SEO-Features für das Payload CMS Multi-Tenant System. **Wichtig:** Frontends verwenden die **Production-API** (cms.c2sgmbh.de) für SEO-Daten, um konsistente Meta-Tags und Structured Data zu gewährleisten. --- ## API-Endpoints für Frontend ### SEO-Daten abrufen | Endpoint | Beschreibung | |----------|--------------| | `GET /api/globals/seo-settings` | Globale SEO-Konfiguration | | `GET /api/pages?where[slug][equals]=...` | Page-spezifische SEO (meta-Feld) | | `GET /api/posts?where[slug][equals]=...` | Post-spezifische SEO | ### Beispiel: SEO-Settings laden ```typescript // Frontend: SEO-Defaults aus Production laden const seoSettings = await fetch('https://cms.c2sgmbh.de/api/globals/seo-settings') .then(r => r.json()) // Enthält: // - metaDefaults (titleSuffix, defaultDescription, defaultImage) // - organization (name, legalName, logo, foundingDate) // - contact (email, phone, fax) // - address (street, city, country, etc.) // - socialProfiles (Array) // - localBusiness (type, priceRange, openingHours) // - robots (indexing, additionalDisallow) // - verification (google, bing, yandex) ``` ### Beispiel: Page-SEO laden ```typescript // Page mit SEO-Daten laden const page = await fetch( 'https://cms.c2sgmbh.de/api/pages?where[slug][equals]=about&where[tenant][equals]=4&locale=de' ).then(r => r.json()) // page.docs[0].meta enthält: // - title (Page-spezifischer Titel) // - description (Meta-Description) // - image (OG-Image Override) // - noIndex, noFollow (Indexierungssteuerung) ``` --- ## Implementierte Features ### 1. Dynamische Sitemap (`/sitemap.xml`) **Datei:** `/src/app/sitemap.ts` Die Sitemap wird dynamisch aus der Datenbank generiert und enthält: - Startseite (Priorität: 1.0, Änderungshäufigkeit: täglich) - Alle veröffentlichten Seiten (Priorität: 0.8, Änderungshäufigkeit: wöchentlich) - Alle veröffentlichten Posts mit typ-basierter URL (Priorität: 0.6, Änderungshäufigkeit: monatlich) **URL-Schema für Posts:** | Post-Typ | URL-Prefix | |----------|------------| | blog | `/blog/{slug}` | | news | `/news/{slug}` | | press | `/presse/{slug}` | | announcement | `/aktuelles/{slug}` | ### 2. Robots.txt (`/robots.txt`) **Datei:** `/src/app/robots.ts` Konfiguriert Crawler-Zugriff: ``` User-Agent: * Allow: / Disallow: /admin Disallow: /admin/* Disallow: /api/* Disallow: /_next/* Disallow: /media/* User-Agent: Googlebot Allow: / Disallow: /admin Disallow: /api Host: https://cms.c2sgmbh.de Sitemap: https://cms.c2sgmbh.de/sitemap.xml ``` ### 3. Structured Data (JSON-LD) **Datei:** `/src/lib/structuredData.ts` Bietet Helper-Funktionen für Schema.org-konforme JSON-LD Daten: #### Verfügbare Funktionen | Funktion | Beschreibung | |----------|--------------| | `generateOrganizationSchema()` | Organization Schema | | `generateArticleSchema()` | Article Schema für Blog-Posts | | `generateNewsArticleSchema()` | NewsArticle Schema | | `generateWebPageSchema()` | WebPage Schema | | `generateBreadcrumbSchema()` | BreadcrumbList Schema | | `generateFAQSchema()` | FAQPage Schema | | `generateReviewSchema()` | Review/Testimonial Schema | | `generateAggregateRatingSchema()` | AggregateRating Schema | | `generateLocalBusinessSchema()` | LocalBusiness Schema | | `generateWebSiteSchema()` | WebSite Schema mit SearchAction | | `combineSchemas()` | Kombiniert mehrere Schemas | | `renderJsonLd()` | Sicheres Rendering von JSON-LD | #### Verwendungsbeispiel (Frontend) ```tsx // src/components/seo/JsonLd.tsx import { generateArticleSchema, renderJsonLd } from '@/lib/structuredData' interface BlogPostProps { post: { title: string excerpt: string slug: string publishedAt: string updatedAt: string author?: { name: string } featuredImage?: { url: string } categories?: Array<{ title: string }> } } export default function BlogPost({ post }: BlogPostProps) { const schema = generateArticleSchema({ title: post.title, description: post.excerpt, slug: post.slug, publishedAt: post.publishedAt, updatedAt: post.updatedAt, author: post.author, featuredImage: post.featuredImage, categories: post.categories, }, 'https://complexcaresolutions.de') // Tenant-Domain return ( <>