From 6b7d673ebbd68899d5effb4a5327daaabfa1df94 Mon Sep 17 00:00:00 2001 From: Eason WaveKat Date: Tue, 21 Jul 2026 19:20:17 +1200 Subject: [PATCH 1/7] feat(footer): link prompt generator and alternatives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The footer nav had fallen behind the site: it still listed the six sections that existed when it was written, missing the prompt generator landing page and the alternatives hub. Both are SEO/GEO front doors that benefit most from a sitewide internal link. Add both, and drop the docs link — docs are synced from the private wavekat-voice repo and are English-only, so it was the one entry that couldn't be localized (and the only one missing a trailing slash). Lowercase footerAbout across the Latin-script locales so every label matches the lowercase chrome style; the string is footer-only, so nothing else is affected. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011wM5WdWCFkRyjvMEBJdZKb --- src/components/Footer.astro | 3 ++- src/lib/i18n.ts | 5 ++++- src/lib/ui/de.ts | 3 ++- src/lib/ui/es.ts | 3 ++- src/lib/ui/fr.ts | 3 ++- src/lib/ui/it.ts | 3 ++- src/lib/ui/ja.ts | 1 + src/lib/ui/ko.ts | 1 + src/lib/ui/zh-hant.ts | 1 + 9 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 5e73bda..3b1a823 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -12,9 +12,10 @@ const localeHref = (path: string) => // Sitemap links reuse the localized chrome strings — no new translations needed. const links = [ { href: localeHref('/voice/'), label: ui.navVoice }, + { href: localeHref('/voice/alternatives/'), label: ui.subAlternatives }, { href: localeHref('/voice/download/'), label: ui.subDownload }, { href: localeHref('/voice/changelog/'), label: ui.subChangelog }, - { href: '/docs', label: ui.navDocs }, + { href: localeHref('/voice/prompts/'), label: ui.footerPrompts }, { href: localeHref('/blog/'), label: ui.navBlog }, { href: localeHref('/about/'), label: ui.footerAbout }, ]; diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index 77f4fd0..3585937 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -215,6 +215,7 @@ export interface UIStrings { footerEmail: string; footerSource: string; footerAbout: string; + footerPrompts: string; notFoundTitle: string; notFoundBody: string; notFoundHome: string; @@ -266,7 +267,8 @@ const strings: Record = { talkWritePost: ' directly.', footerEmail: 'Email us', footerSource: 'View source on GitHub', - footerAbout: 'About', + footerAbout: 'about', + footerPrompts: 'prompt generator', notFoundTitle: "Page not found", notFoundBody: "The page you're looking for doesn't exist or has moved.", notFoundHome: "Go to the homepage", @@ -299,6 +301,7 @@ const strings: Record = { footerEmail: '给我们发邮件', footerSource: '在 GitHub 上查看源码', footerAbout: '关于', + footerPrompts: '语音生成器', notFoundTitle: "页面不存在", notFoundBody: "您要找的页面不存在或已被移动。", notFoundHome: "返回首页", diff --git a/src/lib/ui/de.ts b/src/lib/ui/de.ts index 2192d7d..08a0ff3 100644 --- a/src/lib/ui/de.ts +++ b/src/lib/ui/de.ts @@ -24,7 +24,8 @@ export const ui: UIStrings = { talkWritePre: 'Oder schreiben Sie direkt an ', talkWritePost: '.', footerEmail: 'Schreiben Sie uns', - footerAbout: 'Über uns', + footerAbout: 'über uns', + footerPrompts: 'sprachgenerator', notFoundTitle: "Seite nicht gefunden", notFoundBody: "Die gesuchte Seite existiert nicht oder wurde verschoben.", notFoundHome: "Zur Startseite", diff --git a/src/lib/ui/es.ts b/src/lib/ui/es.ts index 9b4b9ed..50f2c3b 100644 --- a/src/lib/ui/es.ts +++ b/src/lib/ui/es.ts @@ -24,7 +24,8 @@ export const ui: UIStrings = { talkWritePre: 'O escriba directamente a ', talkWritePost: '.', footerEmail: 'Escríbanos', - footerAbout: 'Acerca de', + footerAbout: 'acerca de', + footerPrompts: 'generador de voz', notFoundTitle: "Página no encontrada", notFoundBody: "La página que buscas no existe o se ha movido.", notFoundHome: "Ir a la página de inicio", diff --git a/src/lib/ui/fr.ts b/src/lib/ui/fr.ts index 1d4461f..2215ee1 100644 --- a/src/lib/ui/fr.ts +++ b/src/lib/ui/fr.ts @@ -24,7 +24,8 @@ export const ui: UIStrings = { talkWritePre: 'Ou écrivez directement à ', talkWritePost: '.', footerEmail: 'Écrivez-nous', - footerAbout: 'À propos', + footerAbout: 'à propos', + footerPrompts: 'générateur vocal', notFoundTitle: "Page introuvable", notFoundBody: "La page que vous cherchez n'existe pas ou a été déplacée.", notFoundHome: "Aller à l'accueil", diff --git a/src/lib/ui/it.ts b/src/lib/ui/it.ts index f6d85d2..607be07 100644 --- a/src/lib/ui/it.ts +++ b/src/lib/ui/it.ts @@ -24,7 +24,8 @@ export const ui: UIStrings = { talkWritePre: 'Oppure scrivi direttamente a ', talkWritePost: '.', footerEmail: 'Scrivici un’email', - footerAbout: 'Chi siamo', + footerAbout: 'chi siamo', + footerPrompts: 'generatore vocale', notFoundTitle: "Pagina non trovata", notFoundBody: "La pagina che cerchi non esiste o è stata spostata.", notFoundHome: "Vai alla home", diff --git a/src/lib/ui/ja.ts b/src/lib/ui/ja.ts index e774dd5..014936d 100644 --- a/src/lib/ui/ja.ts +++ b/src/lib/ui/ja.ts @@ -25,6 +25,7 @@ export const ui: UIStrings = { talkWritePost: ' まで直接ご連絡ください。', footerEmail: 'メールを送る', footerAbout: 'WaveKat について', + footerPrompts: '音声ジェネレーター', notFoundTitle: "ページが見つかりません", notFoundBody: "お探しのページは存在しないか、移動しました。", notFoundHome: "ホームへ戻る", diff --git a/src/lib/ui/ko.ts b/src/lib/ui/ko.ts index 9fb0b06..68bb68a 100644 --- a/src/lib/ui/ko.ts +++ b/src/lib/ui/ko.ts @@ -25,6 +25,7 @@ export const ui: UIStrings = { talkWritePost: '(으)로 직접 메일을 보내셔도 됩니다.', footerEmail: '이메일 보내기', footerAbout: '소개', + footerPrompts: '음성 생성기', notFoundTitle: "페이지를 찾을 수 없습니다", notFoundBody: "찾으시는 페이지가 존재하지 않거나 이동되었습니다.", notFoundHome: "홈으로 돌아가기", diff --git a/src/lib/ui/zh-hant.ts b/src/lib/ui/zh-hant.ts index 21c19f2..4463a9e 100644 --- a/src/lib/ui/zh-hant.ts +++ b/src/lib/ui/zh-hant.ts @@ -25,6 +25,7 @@ export const ui: UIStrings = { talkWritePost: '。', footerEmail: '寄信給我們', footerAbout: '關於', + footerPrompts: '語音產生器', notFoundTitle: "找不到頁面", notFoundBody: "您要找的頁面不存在或已被移動。", notFoundHome: "返回首頁", From 90bf1491e39926fc18af39e5fd880a2fd6ef8e2f Mon Sep 17 00:00:00 2001 From: Eason WaveKat Date: Tue, 21 Jul 2026 19:28:25 +1200 Subject: [PATCH 2/7] feat(footer): group links into two labelled columns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A flat seven-link grid didn't communicate that half the entries belong to the Voice desktop app and half are sitewide. Split it into a "WaveKat Voice" column (overview, alternatives, download, what's new) and a "more" column (prompt generator, blog, about) — the prompt generator sits in the second group because it's a platform tool, not part of the Voice app. The heading also frees the first link to read "overview" (reusing the existing subOverview string) instead of repeating "voice". Adds footerMore across the nine locales; the Voice heading is the brand name and stays untranslated. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011wM5WdWCFkRyjvMEBJdZKb --- src/components/Footer.astro | 52 +++++++++++++++++++++++++------------ src/lib/i18n.ts | 3 +++ src/lib/ui/de.ts | 1 + src/lib/ui/es.ts | 1 + src/lib/ui/fr.ts | 1 + src/lib/ui/it.ts | 1 + src/lib/ui/ja.ts | 1 + src/lib/ui/ko.ts | 1 + src/lib/ui/zh-hant.ts | 1 + 9 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 3b1a823..0fb964f 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -9,15 +9,28 @@ const ui = t(lang); const localeHref = (path: string) => localesForPath(path).includes(lang) ? localizedPath(path, lang) : path; -// Sitemap links reuse the localized chrome strings — no new translations needed. -const links = [ - { href: localeHref('/voice/'), label: ui.navVoice }, - { href: localeHref('/voice/alternatives/'), label: ui.subAlternatives }, - { href: localeHref('/voice/download/'), label: ui.subDownload }, - { href: localeHref('/voice/changelog/'), label: ui.subChangelog }, - { href: localeHref('/voice/prompts/'), label: ui.footerPrompts }, - { href: localeHref('/blog/'), label: ui.navBlog }, - { href: localeHref('/about/'), label: ui.footerAbout }, +// Two columns: the WaveKat Voice desktop app, then everything sitewide. The +// prompt generator sits in the second group deliberately — it's a platform +// tool, not part of the Voice app. Link labels reuse the localized chrome +// strings; only the second heading needed a new one. +const groups = [ + { + heading: 'WaveKat Voice', // brand name — never translated + links: [ + { href: localeHref('/voice/'), label: ui.subOverview }, + { href: localeHref('/voice/alternatives/'), label: ui.subAlternatives }, + { href: localeHref('/voice/download/'), label: ui.subDownload }, + { href: localeHref('/voice/changelog/'), label: ui.subChangelog }, + ], + }, + { + heading: ui.footerMore, + links: [ + { href: localeHref('/voice/prompts/'), label: ui.footerPrompts }, + { href: localeHref('/blog/'), label: ui.navBlog }, + { href: localeHref('/about/'), label: ui.footerAbout }, + ], + }, ]; let siteVersion: string; @@ -67,14 +80,19 @@ try { -