From 797d9d42fe5fc2c45d167f9fb12d9d37fe5732b3 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 24 Jul 2026 21:10:33 +0000 Subject: [PATCH] Custom post content blocks (images/gallery/video/quote) + backend-driven SEO settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RichText.tsx switched to Payload's official React renderer + custom JSXConverters (same call signature, LiveRichText/LivePostContent untouched) — needed to render the new Lexical Blocks the Payload repo's Posts.content just gained. Converters follow the existing CMS-image convention (relative + aspect-[...] + fill + object-cover); the video block resolves YouTube/Vimeo links to an iframe embed. New getSeoSettings() fetcher (same pattern as getKleinunternehmer()), app/layout.tsx now generateMetadata() reading it with the same fallback values it used to hardcode. Per-post SEO overrides (seoTitle/ seoDescription/seoImage) wired into the blog detail page's metadata, falling back to title/excerpt/thumbnail when empty. Also fixed while auditing every page's metadata: missing descriptions on 3 konto pages, a static title on the dynamic order-detail route, and missing OG images on /shop and /blog. --- README.md | 38 + app/blog/[slug]/page.tsx | 23 +- app/blog/page.tsx | 7 + app/components/RichText.tsx | 289 +- app/konto/bestellungen/[orderNumber]/page.tsx | 18 +- app/konto/passwort-vergessen/page.tsx | 1 + app/konto/passwort-zuruecksetzen/page.tsx | 1 + app/konto/profil/page.tsx | 1 + app/layout.tsx | 44 +- app/lib/payload.ts | 64 + app/shop/page.tsx | 1 + package-lock.json | 3945 ++++++++++++++++- package.json | 1 + 13 files changed, 4249 insertions(+), 184 deletions(-) diff --git a/README.md b/README.md index eabc1dc..a030126 100644 --- a/README.md +++ b/README.md @@ -1441,6 +1441,44 @@ calling out specifically since they add new shared components: each page's heading — not nested inside the sidebar's `hidden lg:...` wrapper, which would hide it too regardless of its own `lg:hidden` class. +## Custom post content blocks, and SEO settings (2026-07-24) + +`app/components/RichText.tsx` switched from a small hand-rolled Lexical +JSON→JSX walker to Payload's official `@payloadcms/richtext-lexical/react` +renderer + custom `JSXConverters` — needed once the Payload repo's +`Posts.content` gained custom Lexical Blocks (`Bild`/`Bildergalerie`/`Video`/ +`Zitat`, see the Payload README's own section on this), which the old +hand-rolled `switch` had no case for at all. Kept the exact same exported +call signature (`RichText({ content, quoteLabel })`), so `LiveRichText.tsx` +and `app/blog/[slug]/components/LivePostContent.tsx` needed zero changes. +`extractHeadings()`/`headingId()` (used by `SectionTOC` on legal pages) stay +an independent, minimal walk over the raw JSON, unrelated to the new +renderer — legal pages don't use Blocks. + +Block converters follow this project's established "CMS-sourced image" +convention (`relative` + `aspect-[…]` + `next/image fill` + `object-cover`, +see the blog thumbnail treatment) — a gallery block renders as a +`grid-cols-2` grid, a video block resolves a YouTube/Vimeo URL into an +`