DEV Community

Cover image for Localizing a Tauri App for Japanese and English — What Actually Works
hiyoyo
hiyoyo

Posted on

Localizing a Tauri App for Japanese and English — What Actually Works

All tests run on an 8-year-old MacBook Air.
All results from shipping 7 Mac apps as a solo developer. No sponsored opinion.
All my apps ship in Japanese and English. Not separate codebases — one app, two languages, runtime switching.
Here's the implementation that works in production.

Why bother with dual language
Japanese users convert better on Japanese UI with JPY pricing. English users are a global market. Both are worth serving. One codebase is the only viable approach for a solo developer.

The i18n library
I use react-i18next in the React frontend:
bashnpm install i18next react-i18next
typescript// i18n.ts
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'

i18n.use(initReactI18next).init({
resources: {
en: { translation: enTranslations },
ja: { translation: jaTranslations },
},
lng: 'en',
fallbackLng: 'en',
})

export default i18n

Translation file structure
typescript// en.json
{
"sync": {
"start": "Start Sync",
"stop": "Stop Sync",
"status": {
"idle": "Ready",
"running": "Syncing...",
"complete": "Sync complete",
"error": "Sync failed"
}
},
"device": {
"connect": "Connect Device",
"disconnect": "Disconnect",
"notFound": "No device found"
}
}

// ja.json
{
"sync": {
"start": "同期開始",
"stop": "同期停止",
"status": {
"idle": "待機中",
"running": "同期中...",
"complete": "同期完了",
"error": "同期エラー"
}
},
"device": {
"connect": "デバイスを接続",
"disconnect": "切断",
"notFound": "デバイスが見つかりません"
}
}

Detecting system language
Get the system locale from Rust and pass to the frontend on launch:
rust#[tauri::command]
fn get_system_locale() -> String {
std::env::var("LANG")
.unwrap_or_default()
.split('.')
.next()
.unwrap_or("en")
.to_string()
}
typescriptconst locale = await invoke('get_system_locale')
const lang = locale.startsWith('ja') ? 'ja' : 'en'
i18n.changeLanguage(lang)

Localizing Gemini prompts
AI prompts need localization too. Japanese users get Japanese responses:
rustpub fn build_prompt(input: &str, lang: &str) -> String {
match lang {
"ja" => format!(
"以下のエラーを日本語で説明し、修正方法を提案してください。\nエラー: {}",
input
),
_ => format!(
"Explain this error and suggest a fix.\nError: {}",
input
),
}
}
A Japanese user who gets an English AI response will be confused. Localize the prompts.

The separate Gumroad listings
One app binary, two Gumroad listings — JP and EN with different prices and descriptions. The JP listing uses JPY pricing. The EN listing uses USD.
Users self-select. The binary is identical. The storefront is localized.

The verdict
react-i18next + system locale detection + localized AI prompts covers the full localization stack. The overhead is low. The market expansion is real.

If this was useful, a ❤️ helps more than you'd think — thanks!
Hiyoko PDF Vault → https://hiyokoko.gumroad.com/l/HiyokoPDFVault
X → @hiyoyok

Top comments (0)