From 00e77ecf0525c55760a0c3bcfa18d4c7d0822215 Mon Sep 17 00:00:00 2001 From: Padreug Date: Wed, 27 May 2026 11:33:57 +0200 Subject: [PATCH] feat: i18n migration + French + Spanish translations + locale switcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every visitor-facing string now flows through namespaced i18n keys (home.*, portfolio.*, projects..*, contact.*, form.*, etc.), including alt text and form-validation error messages. Project copy (name / eyebrow / intro / coverAlt) is looked up by slug from the locale bundle rather than hard-coded in src/data/projects.ts — project shape stays English-default for fallback values, but the runtime resolves via i18n. Adds a complete fr.json and rewrites es.json from the boilerplate demo content. Three locales total: en (default), fr, es. The initial locale picks the persisted `ewd:locale` value, falls back to a navigator.language match, then to en. LocaleSwitcher (a small EN/FR/ES dropdown in the header next to the theme toggle) writes to localStorage so the choice survives navigation and reload. Visible at both desktop and mobile breakpoints. The ContactForm's zod schema is rebuilt as a computed so error messages re-translate live when the locale changes. The PrivacyBlurb uses with a #nostr slot so "Nostr network" can be the emphasized inline span across all three locales. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/contact/ContactForm.vue | 155 ++++++++++++---------- src/components/contact/PrivacyBlurb.vue | 16 ++- src/components/layout/LocaleSwitcher.vue | 42 ++++++ src/components/layout/SiteFooter.vue | 10 +- src/components/layout/SiteHeader.vue | 24 ++-- src/components/layout/ThemeToggle.vue | 4 +- src/components/projects/ProjectDetail.vue | 21 +-- src/components/projects/ProjectImage.vue | 7 +- src/i18n/index.ts | 30 ++++- src/i18n/locales/en.json | 135 ++++++++++++++++++- src/i18n/locales/es.json | 135 ++++++++++++++++++- src/i18n/locales/fr.json | 134 +++++++++++++++++++ src/views/ContactView.vue | 10 +- src/views/HomeView.vue | 47 ++++--- src/views/PortfolioView.vue | 24 +++- 15 files changed, 649 insertions(+), 145 deletions(-) create mode 100644 src/components/layout/LocaleSwitcher.vue create mode 100644 src/i18n/locales/fr.json diff --git a/src/components/contact/ContactForm.vue b/src/components/contact/ContactForm.vue index 62f4210..46acb58 100644 --- a/src/components/contact/ContactForm.vue +++ b/src/components/contact/ContactForm.vue @@ -1,5 +1,6 @@ @@ -125,12 +143,15 @@ function placeholderFor(method: string | undefined): string {
- Your name (optional) + + {{ t('form.name.label') }} + {{ t('form.name.optional') }} + @@ -141,15 +162,15 @@ function placeholderFor(method: string | undefined): string {
- Reach me via + {{ t('form.method.label') }} - Whatever is easiest for you — the studio will use exactly this. + {{ t('form.value.description') }} @@ -178,11 +199,11 @@ function placeholderFor(method: string | undefined): string { - Your message + {{ t('form.message.label') }}