# Schnittstellenreview — fabular.pages.dev · Social-Sharing / SEO / GEO

Re-check (2026-06-07) of the 2026-06-06 link-preview finding, widened to SEO + GEO,
in the **Weiling Schnittstellenreview** format (spec-vs-reality, three severities,
count-everything). Companion HTML section deployed to `social-share-briefing.pages.dev`.

## Header block

- **Prüfer:** 44up Observatory
- **Gegenstand:** `fabular.pages.dev` — *Fresh Haven*, das fab4minds „fabular." Demo-Storefront (statischer Export auf Cloudflare Pages)
- **Geprüft:** Startseite · Produktseiten · `sitemap.xml` · `robots.txt` · `llms.txt` · `/opengraph-image`
- **Datum Review:** 2026-06-07 (Re-Check des `2026-06-06e`-Befunds)
- **Befunde gesamt:** 6 — 2 kritisch · 2 funktional · 2 strukturell
- **Methode:** read-only `curl` (HTTP/1.1 + HTTP/2, mehrere UAs) + Playwright Browser-`fetch()`. Keine DB-Writes. **Beobachtet** vs. **abgeleitet** durchgehend markiert (eine Egress-IP, kein öffentlicher WhatsApp-Validator).

## Zusammenfassung

Seit dem Link-Vorschau-Audit (`2026-06-06e`) hat das Demo **nachgebessert**: die Startseite
trägt jetzt ein `og:image`, Produktseiten haben **produktspezifische** `og:title`/`og:description`,
der schema.org-Graph ist der reichste im Sektor, `robots.txt` öffnet für alle KI-Crawler,
`llms.txt` ist strukturiert und nennt „150+". Die Lücke ist damit von **fehlenden** zu
**uneingelösten** Tags gewandert: Das angekündigte OG-Bild liefert einen leeren Body, die
sitemap listet 153 Produkt-URLs, die 404en, die Produktzahl steht in drei widersprüchlichen
Werten (40 / 150+ / 2141), und die Twitter-Karte erbt auf Produktseiten weiter den generischen
Startseiten-Titel. **Ein Storefront, der korrekt *ankündigt*, aber nicht *einlöst*, was er ankündigt.**

## Befundzahl

| Schwere | n | Definition |
|---|---|---|
| **Kritisch** | 2 | Bricht oder liefert still Falsches — ein spec-treuer Konsument scheitert oder verarbeitet falsch. |
| **Funktional** | 2 | Funktioniert mechanisch, widerspricht/täuscht aber den Konsumenten. |
| **Strukturell** | 2 | Bricht nicht, lügt nicht, wirkt aber unsauber. |

## Das Richtige im System (Positivfall)

Das Demo ist das **stärkste SEO/GEO-Gerüst der drei** im `2026-06-06e` geprüften Storefronts:
vollständig server-gerendert (**keine** JS-Mauer — `curl` == Browser), der reichste
schema.org-Graph im Sektor (`Product` · `Offer` · `AggregateRating` · `BreadcrumbList` ·
`FAQPage` · `MerchantReturnPolicy` · `OfferShippingDetails` · `Organization`), `robots.txt`
erlaubt explizit alle 16 KI-/Such-Bots (GPTBot, ClaudeBot, anthropic-ai, PerplexityBot,
Googlebot-Extended, cohere-ai, meta-externalagent, CCBot …), eine strukturierte 120-Zeilen-`llms.txt`
mit Kernfakten + Kategorien. **Die Defekte sind Nutzlast und Konsistenz — nicht Architektur.**
Das ist die Umkehrung der Sektor-Norm (`2026-06-05`): fab4minds-*Tenants* sind JS-verwallt
(KI 27); das fab4minds-*Demo* ist die KI-100-Referenz. Diese Achse bleibt intakt.

---

## Befunde — pro Achse

### A · Social-Sharing (OG / Twitter)

**Kritisch**

- **K1 — `og:image` deklariert, Body leer.** Start- und Produktseite deklarieren jetzt ein
  `og:image` (`/opengraph-image`, 1200×630 bzw. 800×800, `image/png`). Der Endpoint antwortet
  **HTTP 200, content-type `image/png`, aber 0 Bytes** — `content-length` fehlt, `size_download=0`
  unter `curl --http1.1` *und* HTTP/2 *und* mit `facebookexternalhit`-UA; im echten Browser-`fetch()`
  von der Live-Origin: `status 200, type image/png, blobSize 0`. Beim Direkt-Navigieren hängt der
  Browser, bis das Timeout greift (Header ohne Body). **Konsequenz:** WhatsApp/Facebook/X zeigen
  weiter eine **bildlose Karte** — trotz jetzt korrekter Tags. *Beobachtet.* Ursache (der
  OG-Image-Generator / `ImageResponse`-Route liefert auf diesem statischen Pages-Deploy einen
  leeren Body) *abgeleitet.*
  > Der `2026-06-06e`-Fix („`og:image` ergänzen") ist in den **Tags** gelandet — aber das Bild
  > selbst fehlt weiter, jetzt aus einem anderen Grund. Re-Check-Wert: der sichtbare Defekt
  > (bildlose WhatsApp-Karte) überlebt den Fix.

**Funktional**

- **F1 — Produkt-Twitter-Karte trägt den generischen Startseiten-Titel.** Auf
  `/produkt/bio-karotten-1kg` sind `og:title`/`og:description` produktspezifisch
  („Bio-Karotten kaufen | Fresh Haven"), `twitter:title`/`twitter:description` aber die
  **Startseiten-Texte** („Fresh Haven – Frische Lebensmittel online bestellen"). Geteilte
  Produkt-Links auf X zeigen den falschen (generischen) Titel. *Verbesserung* ggü. `2026-06-06e`
  (dort waren auch `og:` generisch) — nur `twitter:` hinkt nach. *Beobachtet.*

**Strukturell**

- **S1 — Widersprüchliche `og:image`-Maße für dasselbe (leere) Asset.** Dieselbe URL
  `/opengraph-image` wird mit **1200×630** (Startseite) und **800×800** (Produkt) deklariert.
  Selbst bei gefülltem Body würde eine der beiden Deklarationen lügen.
- **S2 — `og:image` trägt Cache-Buster-Query, `twitter:image` nicht.** `og:image` =
  `/opengraph-image?ae8029deafe7bafd`, `twitter:image` = `/opengraph-image` — zwei URLs für
  eine Quelle. Kosmetisch (beide leer), aber Zeichen für uneinheitliche Generierung.

### B · SEO

**Kritisch**

- **K2 — 153 sitemap-Produkt-URLs (~7,1%) liefern 404.** `sitemap.xml` listet **2141**
  `/produkt/`-URLs (+ 130 `/rezepte/`, 23 `/kategorie/`, 11 `/produzenten/` …). **153 davon
  tragen rohe Umlaute** (ä/ö/ü) im Slug und liefern durchgängig 404. Stichprobe:
  **17/17 Umlaut-Slugs tot · 43/43 ASCII-Slugs 200** (Kontroll-ASCII inkl. transliterierter
  Slugs wie `gebaeck-mix-500g` → 200). Beispiele tot: `leberkäse-300g`, `paranüsse-150g`,
  `entenbrust-geräuchert-150g`, `eistee-grün-1l`. **Konsequenz:** Crawler & LLMs, die der
  sitemap folgen, laufen auf ~7% der Produkte ins Leere; diese Produkte sind für Suche/KI
  unsichtbar. *Beobachtet.* Ursache (sitemap emittiert NFC-Rohumlaut, der Router serviert
  transliterierte Slugs `ä→ae` — beide stimmen für diese Cohorte nicht überein; ein Teil ist
  unter *keiner* Slug-Variante deployt) *abgeleitet.*
  > Hinweis: `leberkäse` *und* `leberkaese` 404en beide — die Transliteration ist also nicht
  > die saubere 1:1-Lösung; ein Teil der gelisteten Umlaut-Produkte existiert schlicht nicht.

**Funktional**

- **F2 — Drei widersprüchliche Produktzahlen.** Die Katalog-Größe steht dreifach:
  meta-description **„Über 40 Produkte"** · `llms.txt` **„über 150 / 150+"** · `sitemap.xml`
  **2141** echte Produktseiten (Stichproben-200-Rate ~90%). Der indexierte Google-Snippet
  unterzählt den realen Katalog um das **~50-fache**, `llms.txt` um das ~14-fache.
  Cross-Link: der „über 40"→„150+"-Undercount tauchte schon im MCP-Audit (`2026-06-06d` §3.3)
  auf — `llms.txt` wurde dort korrigiert, die **meta-description trägt den alten Wert weiter**.
  *Beobachtet.*

### C · GEO (KI-Zugänglichkeit)

**Positivfall — kein Kritisch/Funktional.** `robots.txt` erlaubt explizit alle 16 geprüften
KI-/Such-Bots (`Allow: /` je Agent), nennt `Host` + `Sitemap`. `llms.txt` ist vorhanden,
120 Zeilen, strukturiert (Kernfakten, Sortiment, Kategorien-Links). Diese Achse ist die
stärkste des Storefronts. **Einziger GEO-relevanter Defekt ist die Konsistenz** (F2 oben:
`llms.txt` „150+" ≠ sitemap 2141 ≠ meta „40") — eine LLM, die `llms.txt` als Wahrheit nimmt,
zitiert eine ~14× zu kleine Sortimentszahl.

---

## Systemische Probleme

Ein Muster über alle drei Achsen: **deklariert ≠ eingelöst.** Das `og:image`-Tag existiert,
das Bild nicht (K1). Die sitemap behauptet 2141 Produkte, 153 davon existieren nicht unter der
gelisteten URL (K2). Drei Surfaces nennen drei Produktzahlen (F2). Die Twitter-Karte verspricht
ein Produkt, liefert den Shop-Namen (F1).

Die **Schnittstelle** — das, was Maschinen lesen (Tags, sitemap, llms.txt, schema.org) — ist
sauber *spezifiziert*; der dahinterliegende Build hält die Zusage nicht. Das ist kein
Architektur-, sondern ein **Generierungs-/Konsistenz-Problem**: Sitemap-Generator, OG-Image-Route
und Copy-Texte laufen auseinander, weil keine gemeinsame Quelle (eine Produktliste, eine
Slug-Normalisierung, ein Asset-Pipeline-Schritt) sie bindet. Genau die Klasse Befund, die ein
Demo am leichtesten übersieht — es *zeigt* gut und wird selten end-to-end als geteilter Link
oder als sitemap-folgender Crawler getestet.

## Empfohlene Sofortmaßnahmen

| Prio | Maßnahme |
|---|---|
| **Hoch** | **1.** `/opengraph-image` reparieren, sodass es echte PNG-Bytes liefert (der OG-Image-Generator gibt auf diesem Pages-Deploy einen leeren Body) — stellt das Bild auf *jeder* WhatsApp/FB/X-Karte in einem Zug her. |
| **Hoch** | **2.** `sitemap.xml` mit derselben Slug-Normalisierung regenerieren, die der Router nutzt, **oder** die 153 Umlaut-Produkte unter der gelisteten URL deployen — entfernt ~7% tote URLs. |
| **Mittel** | **3.** Produktspezifische `twitter:title`/`twitter:description` setzen (heute generisch). |
| **Mittel** | **4.** Produktzahl über meta-description / `llms.txt` / sitemap auf **einen** wahren Wert versöhnen. |
| **Niedrig** | **5.** Deklarierte `og:image`-Maße an das tatsächliche Asset angleichen (1200×630 vs 800×800). |

---

*Methode: [`README.md`](README.md) · Schnittstellenreview-Form: `knowledge/methodology/interface-review-methodology.md`.
Vor-Befund (Social-Sharing, 3 Storefronts): [`2026-06-06e-social-sharing-link-preview-audit.md`](2026-06-06e-social-sharing-link-preview-audit.md).
Alle Tag-/Asset-Fakten beobachtet (curl + Playwright); Renderer-Verhalten (welcher Crawler welches Tag liest)
laut OG-/Twitter-Spec abgeleitet, nicht im Renderer beobachtet.*
