From f47f7989e0bae8464f471e51fdad994f3d57aaee Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Sat, 20 Jun 2026 18:19:19 +0200 Subject: [PATCH] fix(footer): default nav + tagline when the tenant's CMS footer is empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unom tenant's footer doc has no sections yet (the multi-tenant migration backfilled the old footer to the punktfunk tenant), so the footer rendered as an empty, near-invisible bar. Render a sensible default (Übersicht/Rechtliches links + site tagline) when there are no CMS sections; CMS content overrides it once the unom footer is populated. Co-Authored-By: Claude Opus 4.8 (1M context) --- messages/de.json | 8 ++++- messages/en.json | 8 ++++- src/components/Footer.tsx | 67 ++++++++++++++++++++++++++++++++------- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/messages/de.json b/messages/de.json index 63e2160..eea1396 100644 --- a/messages/de.json +++ b/messages/de.json @@ -14,5 +14,11 @@ "blog_empty": "Noch keine Beiträge.", "blog_all": "Alle Beiträge", "blog_latest_heading": "Aus dem Blog", - "blog_back": "Blog" + "blog_back": "Blog", + + "footer_overview": "Übersicht", + "footer_home": "Startseite", + "footer_legal": "Rechtliches", + "footer_imprint": "Impressum", + "footer_privacy": "Datenschutz" } diff --git a/messages/en.json b/messages/en.json index 56c957c..b5f2e0b 100644 --- a/messages/en.json +++ b/messages/en.json @@ -14,5 +14,11 @@ "blog_empty": "No posts yet.", "blog_all": "All posts", "blog_latest_heading": "From the blog", - "blog_back": "Blog" + "blog_back": "Blog", + + "footer_overview": "Overview", + "footer_home": "Home", + "footer_legal": "Legal", + "footer_imprint": "Imprint", + "footer_privacy": "Privacy" } diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index aa46e4d..54eb2c7 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -1,5 +1,6 @@ import { getRouteApi } from "@tanstack/react-router"; import type { NavigationLink, NavigationSection } from "@/lib/cms"; +import { m } from "@/paraglide/messages"; import Section from "./Section"; const rootApi = getRouteApi("__root__"); @@ -7,24 +8,33 @@ const rootApi = getRouteApi("__root__"); export default function Footer() { const { footer } = rootApi.useLoaderData(); const sections: NavigationSection[] = footer?.sections ?? []; - const tagline = footer?.tagline?.trim(); + // Fall back to the site tagline when the CMS footer has none, so the footer + // is never an empty bar. + const tagline = footer?.tagline?.trim() || m.site_tagline(); return (
- {sections.map((group, gi) => ( -
- {group.title &&

{group.title}

} -
- {(group.entries ?? []).map((item: NavigationLink, i) => ( - - {item.label} - - ))} + {sections.length > 0 ? ( + sections.map((group, gi) => ( +
+ {group.title &&

{group.title}

} +
+ {(group.entries ?? []).map((item: NavigationLink, i) => ( + + {item.label} + + ))} +
-
- ))} + )) + ) : ( + // The unom tenant's CMS footer isn't populated yet — show a + // sensible default so the footer is meaningful. Populating the + // footer in the CMS (tenant=unom) overrides this. + + )} {tagline && (
@@ -37,3 +47,36 @@ export default function Footer() {
); } + +function DefaultNav() { + const groups = [ + { + title: m.footer_overview(), + entries: [{ to: "/", label: m.footer_home() }], + }, + { + title: m.footer_legal(), + entries: [ + { to: "/legal/imprint", label: m.footer_imprint() }, + { to: "/legal/privacy", label: m.footer_privacy() }, + ], + }, + ]; + + return ( + <> + {groups.map((group) => ( +
+

{group.title}

+
+ {group.entries.map((item) => ( + + {item.label} + + ))} +
+
+ ))} + + ); +}