fix(footer): default nav + tagline when the tenant's CMS footer is empty
Build & Deploy unom website / build (push) Successful in 26s
Build & Deploy unom website / deploy (push) Successful in 4s

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) <noreply@anthropic.com>
This commit is contained in:
2026-06-20 18:19:19 +02:00
parent 15130ae4df
commit f47f7989e0
3 changed files with 69 additions and 14 deletions
+7 -1
View File
@@ -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"
}
+7 -1
View File
@@ -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"
}
+55 -12
View File
@@ -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 (
<footer className="bg-neutral-accent">
<Section>
<div className="flex flex-row flex-wrap gap-12 w-full pb-8">
{sections.map((group, gi) => (
<div key={group.id ?? gi}>
{group.title && <h3 className="mb-2">{group.title}</h3>}
<div className="flex flex-col">
{(group.entries ?? []).map((item: NavigationLink, i) => (
<a key={item.id ?? `${item.to}-${i}`} href={item.to}>
{item.label}
</a>
))}
{sections.length > 0 ? (
sections.map((group, gi) => (
<div key={group.id ?? gi}>
{group.title && <h3 className="mb-2">{group.title}</h3>}
<div className="flex flex-col">
{(group.entries ?? []).map((item: NavigationLink, i) => (
<a key={item.id ?? `${item.to}-${i}`} href={item.to}>
{item.label}
</a>
))}
</div>
</div>
</div>
))}
))
) : (
// 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.
<DefaultNav />
)}
{tagline && (
<div className="ml-auto mr-0 self-end">
<div className="flex flex-col">
@@ -37,3 +47,36 @@ export default function Footer() {
</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) => (
<div key={group.title}>
<h3 className="mb-2">{group.title}</h3>
<div className="flex flex-col">
{group.entries.map((item) => (
<a key={item.to} href={item.to}>
{item.label}
</a>
))}
</div>
</div>
))}
</>
);
}