Skip to content

feat(i18n): add Japanese localization across the landing site - #20

Open
yanboishere wants to merge 3 commits into
felinics:mainfrom
yanboishere:feat/japanese-i18n
Open

yanboishere wants to merge 3 commits into
felinics:mainfrom
yanboishere:feat/japanese-i18n

Conversation

@yanboishere

@yanboishere yanboishere commented Sep 18, 2026

Copy link
Copy Markdown
Member

Summary

Add Japanese (ja) as a third UI locale alongside English and Chinese, covering every page of the landing site (home, download, waitlist, blogs, legal, 404), and fix a cross-locale SEO title bug found during review.

What's included

  • src/locales/ja.json — full translation of all 273 keys (verified 1:1 key & placeholder parity with en/zh). Terminology for the embedded product demo strings (computerDemo.*) matches the official Japanese locale that ships inside the vendored Memoh app (マーケットプレイス、Botにインストールする、ブラウザー、依存関係、認証する…), so the landing demo reads like the real Japanese product UI.
  • Locale plumbingja registered in i18n.ts (browser detection + validation of the stored preference), 日本語 added to the TopBar language menu, <html lang> now synced globally from App.vue (previously the legal pages never updated it).
  • Embedded demo — the hero iframe now passes lang=ja through; the vendored app already ships a ja locale, only the landing-owned demo-app/mocks/bootstrap.ts was gating it to zh/en.
  • Hardcoded bilingual strings moved into locale filesPricingSection plan copy, HeroShowcase loading text / iframe title, the "And more" platform strip, TopBar aria-labels. The rendered zh/en output is byte-identical to before (verified in-browser).
  • Typography — Noto Sans JP / Noto Serif JP are loaded and swapped in under html:lang(ja), so kana/kanji render with Japanese glyph forms instead of Simplified-Chinese ones (Google Fonts subsets by unicode-range, so non-ja visitors don't download them).
  • SEOja hreflang alternates on home/download/waitlist; blog dates format as 「2026年9月15日」 under ja.
  • Bug fix (all locales): blog SEO titles were rendering as just {title} — vue-i18n parses a raw | as a plural separator, so "{title} | Memoh Blog" silently dropped its suffix. Escaped as {'|'} in all three locales.

Deliberate scope decisions

  • Legal documents stay zh/en (as docs/legal/README.md documents). Japanese users get Japanese page chrome with the English document body; the ?lang= query now round-trips all three locales without flipping the site language (/legal/terms?lang=ja restores the Japanese UI).
  • Blog posts stay in their source languages — ja falls back to the English article, matching the existing fallback design (ja UI chrome + ja dates around it).
  • The WeChat chat demo is adapted, not translated: the en/zh version explains the Japanese phrase 「おつかれ」, which would be nonsense addressed to a Japanese reader — the ja version instead asks what the Chinese phrase 「辛苦了」 means (and the suggested reply 「你也辛苦了」 is correct Chinese).
  • "Pricing" heading and "Get Started" plan CTA stay English, matching the existing zh treatment.

Review

  • Key/structure/placeholder parity across the three locale files checked mechanically (273 keys each; {n}/{date}/{os}/{title}/{plan}/{'@'}/{'|'} all intact).
  • Rendered every page in the browser under ja (and re-verified zh/en for regressions, including byte-identical pricing copy) — language switcher, legal ?lang round-trip, demo iframe chrome in Japanese, JP font application, and clean console all confirmed.
  • Independent native-level localization review pass; its findings (credits term, 反復→修正, ですます register in one string, 読了まで, デバイス向け, ellipsis consistency, コンピュータ→コンピューター unification to match the product UI) are incorporated.
  • vue-tsc -b, full npm run build (including the demo-app build and SPA fallback/demo verification scripts) pass.

owo and others added 3 commits September 18, 2026 18:33
Add ja as a third UI locale alongside en/zh:

- New src/locales/ja.json translating every key (273 keys, full parity
  with en/zh), using the product's official Japanese terminology from
  the embedded Memoh app (マーケットプレイス, Botにインストールする, ブラウザー, …)
- Register ja in i18n.ts with browser-language detection and validation
  of the stored preference; add 日本語 to the TopBar language menu
- Pass lang=ja through to the embedded product demo (the vendored app
  already ships a ja locale; only the landing-owned mocks/bootstrap.ts
  gated it to zh/en)
- Move the remaining hardcoded bilingual strings into locale files:
  PricingSection plan copy, HeroShowcase loading text and iframe title,
  the "And more" platform strip, and the TopBar aria-labels
- Set <html lang> globally from App.vue so it also tracks the locale on
  the legal pages; format blog dates with the ja calendar while post
  bodies fall back to English; add ja hreflang alternates
- Round-trip the legal pages' ?lang= query for all three locales (the
  document body itself stays zh/en by design, other locales read the
  English text)
- Load Noto Sans JP / Noto Serif JP and swap the SC font fallbacks under
  :lang(ja) so kana and kanji render with Japanese glyph forms
- Fix blog SEO titles dropping the " | Memoh Blog" suffix in every
  locale: vue-i18n parsed the raw | as a plural separator; escape it
  as {'|'}

The wechat chat demo is adapted for ja (it teaches the Chinese phrase
辛苦了 instead of explaining おつかれ to a Japanese reader). Adjacent
translations reviewed against the product UI and the zh/en voice.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Move the hardcoded "Pricing" section heading and "Get Started" plan-card
label into the locale files. Japanese shows 料金プラン / 今すぐ始める
(matching the hero and bottom CTA wording); en/zh keep their current
English rendering unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The embedded demo already renders its UI chrome in the visitor's
language, but the scripted content (welcome conversation, session
titles, workspace files, bot/folder names, memories, schedules, the
canned live reply) was a fixed English dataset. Localize all of it for
ja in the landing-owned mocks:

- mocks/locale.ts reads ?lang= once (Node test runs stay English since
  location is undefined there) and bootstrap.ts reuses it
- data.ts: Japanese session titles, all six scripted conversations, the
  memory_search card, workspace files, bot names/descriptions, folder
  names, dependency blurbs (the zh-flavored session is kept, mirroring
  the English dataset's multilingual touch; "Cloud Computer" stays
  English to match the product's own ja locale)
- fixtures.ts: Japanese memories and schedule entries (referenced by the
  weekly-digest reply)
- chat.ts: reply to typed input in Japanese when the visitor writes kana
  or the demo runs in ja; zh/en behavior unchanged

zh and en demos are byte-identical to before; demo mock tests (13) pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant