fix: SEO- und Barrierefreiheits-Luecken auf Kaufentscheidungsseiten schliessen
Konkrete, verifizierte Luecken auf den Seiten, die Kund:innen von Google aus oder per Link erreichen: - Product-JSON-LD auf der Produktdetailseite ergaenzt um "image" (absolute URLs der hochgeladenen Produktfotos) — fehlte bisher trotz vorhandener Bilder und ist fuer Google Rich-Results/Merchant-Listing mit Sternebewertung + Preis im Suchergebnis erforderlich. - Alt-Text fuer echte (hochgeladene) Bilder aussagekraeftiger: ContentImage uebernimmt jetzt das bereits vorhandene, bisher nur auf Platzhalterkacheln sichtbare "label" (Ernte-Jahr/Typ, Kategorie, Ort) mit in den Alt-Text — wirkt projektweit auf Produktkarten, Ernte-Uebersicht/-Detail und Produkt-Teaser. Produktgalerie-Hauptbild zeigt zusaetzlich die Geschmacksnoten im Alt-Text statt nur des Produktnamens. - Checkout: allgemeine Fehlermeldung nach fehlgeschlagenem Absenden bekommt role="alert" und Fokus wird aktiv dorthin verschoben — bisher rein farblich markiert, Screenreader-Nutzer:innen haetten den Fehler beim geldwerten Bestellabschluss sonst gar nicht mitbekommen. - Cart-Drawer und Warenkorb-Seite: Lagerbestand-Hinweise (Ausverkauft/Nur noch N) treffen asynchron erst nach dem ersten Rendern ein — jetzt in einem persistenten aria-live-Wrapper, damit der Uebergang tatsaechlich angesagt wird statt stumm zu bleiben. Geprueft und bereits solide befunden (keine Aenderung noetig): Shop-Kanonical ignoriert bewusst Such-/Filter-Query-Parameter (kein Duplicate-Content-Risiko), Sitemap deckt Produkt- und Ernte-Detailseiten mit echtem lastmod ab, Produktgalerie-Tastaturbedienung ueber echte <button>-Kacheln mit aria-label/aria-current, Cart-Drawer-Fokusfalle/Fokus-Rueckgabe, Mengen-Steller- aria-live, Farbkontrast von text-honey-dark/text-red-700 auf dem Hintergrund (~4.9:1 bzw. ~6.1:1, beide AA-konform). tsc/vitest/build bleiben gruen (142 Tests).
This commit is contained in:
1 parent
0b2196460a
commit
ac432e261b
6 files changed
+67
-16
No files matched your search
@@ -82,6 +82,14 @@ export default async function ProductDetailPage(
|
||||
sku: product.batch?.code ?? product.slug,
|
||||
brand: { "@type": "Brand", name: company.name },
|
||||
category: t.common.categories[product.category],
|
||||
// Nur bei echter Produktfotografie gesetzt (siehe ProductGallery) — ohne
|
||||
// hochgeladene Bilder faellt die Galerie auf reine CSS-Platzhalterkacheln
|
||||
// zurueck, die als "image" im strukturierten Datensatz falsche Tatsachen
|
||||
// vortaeuschen wuerden (Google Rich-Results/Merchant-Anforderung: absolute
|
||||
// URL zu einem echten Produktfoto, keine Platzhaltergrafik).
|
||||
...(product.images.length > 0
|
||||
? { image: product.images.map((src) => `https://${siteConfig.domain}${src}`) }
|
||||
: {}),
|
||||
offers: {
|
||||
"@type": "Offer",
|
||||
priceCurrency: product.currency,
|
||||
@@ -134,7 +142,11 @@ export default async function ProductDetailPage(
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbJsonLd).replace(/</g, "\\u003c") }}
|
||||
/>
|
||||
<Container className="grid md:grid-cols-2 gap-14">
|
||||
<ProductGallery images={product.images} productName={product.name} />
|
||||
<ProductGallery
|
||||
images={product.images}
|
||||
productName={product.name}
|
||||
description={product.tasteTags.join(", ")}
|
||||
/>
|
||||
|
||||
<div>
|
||||
<p className="tracking-wide-caps text-xs text-honey-dark mb-3">
|
||||
|
||||
Reference in new issue
Block a user