From 34a79e371ef35e952400db1b5f88824dc559452c Mon Sep 17 00:00:00 2001 From: LKSNDRTMLKV Date: Wed, 29 Jul 2026 12:41:35 +0200 Subject: [PATCH 1/5] feat(landing): add i18n routing foundation --- site/dpp-landing/astro.config.mjs | 18 +++++- site/dpp-landing/src/components/Footer.astro | 21 ++++--- site/dpp-landing/src/components/Hero.astro | 7 ++- site/dpp-landing/src/components/Nav.astro | 23 ++++--- site/dpp-landing/src/i18n/config.ts | 28 +++++++++ site/dpp-landing/src/i18n/ui.ts | 65 ++++++++++++++++++++ site/dpp-landing/src/layouts/Base.astro | 30 ++++++++- 7 files changed, 171 insertions(+), 21 deletions(-) create mode 100644 site/dpp-landing/src/i18n/config.ts create mode 100644 site/dpp-landing/src/i18n/ui.ts diff --git a/site/dpp-landing/astro.config.mjs b/site/dpp-landing/astro.config.mjs index 23d247a..415b8de 100644 --- a/site/dpp-landing/astro.config.mjs +++ b/site/dpp-landing/astro.config.mjs @@ -12,7 +12,23 @@ import { viteStaticCopy } from 'vite-plugin-static-copy'; export default defineConfig({ site: "https://odal-node.io", - integrations: [sitemap()], + // i18n foundation: only "en" is live. Adding a locale here plus a matching + // entry in src/i18n/ui.ts is the whole extension point — see src/i18n/config.ts. + i18n: { + defaultLocale: "en", + locales: ["en"], + routing: { + prefixDefaultLocale: false, + }, + }, + integrations: [ + sitemap({ + i18n: { + defaultLocale: "en", + locales: { en: "en-US" }, + }, + }), + ], vite: { plugins: [ tailwindcss(), diff --git a/site/dpp-landing/src/components/Footer.astro b/site/dpp-landing/src/components/Footer.astro index 65fe893..6afd008 100644 --- a/site/dpp-landing/src/components/Footer.astro +++ b/site/dpp-landing/src/components/Footer.astro @@ -3,6 +3,11 @@ // Uses the shared brand mark (currentColor variant) tinted ice for the dark band, // so it stays in sync with the asset instead of a hand-rolled inline copy. import OdalMark from "../assets/favicon.svg"; +import { resolveLocale } from "../i18n/config"; +import { useTranslations } from "../i18n/ui"; + +const lang = resolveLocale(Astro.currentLocale); +const t = useTranslations(lang); const year = new Date().getFullYear(); --- @@ -14,10 +19,10 @@ const year = new Date().getFullYear(); Odal Node
- Signed by you. Verified by anyone. + {t.footer.tagline}
- Sovereign Digital Product Passport infrastructure for EU ESPR. + {t.footer.subtagline}
{d}
- Odal Node is built on a proof-bound architecture: the manufacturer's - raw production data is validated and signed locally, on infrastructure - the manufacturer controls, then discarded. Only the signed proof is - stored and served. This is a property of the software, not a policy - promise — it holds regardless of who operates the node. -
did:web
{s.body}
{s.summary}
- The signed passport you publish to a resolver we operate, and the - metadata required to serve it. + {canSee.summary}
- Your private keys (held in-process on your infrastructure), your raw - production data, your supply-chain detail. + {cannotSee.summary}
- The contents of your import files, which the node discards after - validation. + {couldSeeButDoNot.summary}
- + Read the full breakdown →
+ Odal Node is built on a proof-bound architecture: the manufacturer's + raw production data is validated and signed locally, on infrastructure + the manufacturer controls, then discarded. Only the signed proof is + stored and served. This is a property of the software, not a policy + promise — it holds regardless of who operates the node. +
+ + Read the full breakdown, by deployment model → + +