From 20f3171947cb6c966d3bf8fa31a36e6e74ca53da Mon Sep 17 00:00:00 2001 From: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Date: Mon, 31 Aug 2026 09:58:24 +0200 Subject: [PATCH] refactor(nav): the footer promised what only the nav could keep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NAV_ITEMS says "only routes that actually exist belong here — a nav link to a 404 is a lie". The footer carried the same sentence about itself, and then restated six of those routes as its own literal s. Nothing tied the two lists together, so removing a page from the nav left the footer pointing at it with no way to notice. Both files promised the same thing and only one of them could keep it. FOOTER_SECTIONS now names hrefs instead of repeating them, and the footer renders from that. A rename in NAV_ITEMS reaches the footer for free. Where the footer deliberately says something shorter than the nav — "Voting", not "How voting works"; "API", not "Integration" — that is now an explicit `label` override rather than an independently typed second copy. The difference is recorded as a choice instead of looking like drift. The sibling pillars and the source-code link already came from their own SSOTs (ECOSYSTEM_PILLARS, SOLON_GITHUB_URL) and still do. Six tests, mutation-proven: deleting /security from NAV_ITEMS alone — exactly the regression this prevents — fails the suite and names the orphaned footer link. Verify green (lint, typecheck, design:check, 82 tests). Found by a fleet-wide navigation audit across 20 repos. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE --- src/components/ui/footer.tsx | 131 +++++++++----------------- src/lib/__tests__/site-config.test.ts | 79 ++++++++++++++++ src/lib/site-config.ts | 62 ++++++++++++ 3 files changed, 185 insertions(+), 87 deletions(-) create mode 100644 src/lib/__tests__/site-config.test.ts diff --git a/src/components/ui/footer.tsx b/src/components/ui/footer.tsx index e8f0184..0698bda 100644 --- a/src/components/ui/footer.tsx +++ b/src/components/ui/footer.tsx @@ -1,7 +1,10 @@ import Link from "next/link"; import { ECOSYSTEM_PILLARS, SOLON_GITHUB_URL } from "@/lib/config/ecosystem"; +import { FOOTER_SECTIONS, footerLinkLabel } from "@/lib/site-config"; // Only routes that actually exist belong here — a footer link to a 404 is a lie. +// That is now structural rather than a promise: every destination below comes +// from NAV_ITEMS, so a page removed from the nav cannot survive in the footer. export default function Footer() { const siblings = ECOSYSTEM_PILLARS.filter((p) => p.key !== "solon"); @@ -9,93 +12,47 @@ export default function Footer() {