This document describes the multi-language support implementation for the PLC State Decision Framework.
The application supports multiple languages using Vue I18n. Currently supported languages:
- English (en) - Default
- 繁體中文 (zh-TW) - Traditional Chinese
The i18n system is built on top of Vue I18n (v9) and integrated with:
- Vue 3 Composition API
- Pinia store for language preference persistence
- LocalStorage for saving user's language choice
web/src/
├── i18n/
│ ├── index.ts # i18n configuration
│ └── locales/
│ ├── en.json # English translations
│ └── zh-TW.json # Traditional Chinese translations
The i18n instance is configured in web/src/i18n/index.ts:
- Default locale:
en(English) - Fallback locale:
en(English) - Automatic browser language detection: On first visit, the app automatically detects the browser's language preference
- Locale preference is loaded from localStorage on initialization (if previously set)
- Language mapping:
zh-TW,zh-HK,zh-MO→ Traditional Chinese (zh-TW)- All other languages → English (
en)
Users can switch languages via the language selector in the TopBar component:
- Click the translate icon (🌐) in the top-right corner
- Select desired language from the dropdown menu
- The language preference is automatically saved to localStorage
The language preference is managed in the settings store:
locale: Current locale ('en' | 'zh-TW')setLocale(locale): Method to change language and persist to localStorage- Language preference is loaded on app initialization
To add a new translation key:
- Add to English locale (
web/src/i18n/locales/en.json):
{
"newSection": {
"newKey": "English text"
}
}- Add to Traditional Chinese locale (
web/src/i18n/locales/zh-TW.json):
{
"newSection": {
"newKey": "繁體中文文字"
}
}- Use in components:
<template>
<div>{{ $t('newSection.newKey') }}</div>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const message = t('newSection.newKey')
</script>The translation keys are organized by component/feature:
app.*- Application-wide strings (title, etc.)common.*- Common UI elements (buttons, actions)caseList.*- Case list pagecaseView.*- Case view pageanalysisTab.*- Analysis tabdiscussionTab.*- Discussion tabsettingsModal.*- Settings modalinputPanel.*- Input paneltopBar.*- Top bar
All code comments in the codebase are written in English, following best practices for international development teams.
-
Always provide both translations: When adding new UI text, ensure both English and Traditional Chinese translations are added.
-
Use descriptive keys: Translation keys should be descriptive and organized by feature/component.
-
Parameterized translations: Use Vue I18n's parameterization for dynamic content:
{
"message": "System contains {count} states"
}{{ $t('message', { count: 5 }) }}-
Pluralization: Use Vue I18n's pluralization features when needed.
-
Context-aware translations: Some terms (like "Place", "Lifetime", "Consistency") are kept in English as they are technical terms in the PLC framework.
This application uses browser localStorage to store user data locally on the device. This ensures privacy and data security.
The following data is stored in localStorage:
-
Settings (key:
plc-settings):- LLM Provider preference (OpenAI or Google Gemini)
- API Key (encrypted in browser's localStorage)
- Language preference (
enorzh-TW) - Last analysis description
- Last analysis result
- Initialization status
-
Cases (key:
plc-cases):- All analysis cases
- Case descriptions
- Analysis versions and results
- Chat history with AI
- Current selected case
-
Language Preference (key:
plc-locale):- User's language choice
Important points about data storage:
- ✅ All data stays on your device: Nothing is sent to our servers
- ✅ API Key security: Your API key is stored locally and only used to communicate with the LLM provider you choose (OpenAI or Google Gemini)
- ✅ No server-side storage: We don't have access to your data
- ✅ Device-specific: Data is specific to the browser and device you're using
- ✅ User control: You can clear all data by clearing your browser's localStorage
Users can clear all stored data by:
-
Browser Developer Tools:
- Open browser DevTools (F12)
- Go to Application/Storage tab
- Find "Local Storage" → your domain
- Delete keys:
plc-settings,plc-cases,plc-locale
-
Browser Settings:
- Clear browsing data
- Select "Cookies and other site data"
- This will clear localStorage for all sites
-
Programmatic (for developers):
localStorage.removeItem('plc-settings') localStorage.removeItem('plc-cases') localStorage.removeItem('plc-locale')
- Data persists across browser sessions
- Data is cleared when:
- User clears browser data
- User uses incognito/private mode (data cleared when session ends)
- Browser storage quota is exceeded
- Browser localStorage typically has a 5-10MB limit per domain
- The application stores text-based data, so this limit is rarely reached
- If limit is reached, the app will show an error and data won't be saved
Potential improvements:
- Add more languages (e.g., Simplified Chinese, Japanese)
- Implement RTL (Right-to-Left) language support if needed
- Add option to export/import settings and cases
- Implement cloud sync option (optional, user-controlled)
- Add encryption for sensitive data
When updating translations:
- Update both
en.jsonandzh-TW.jsonfiles - Test the application in both languages
- Ensure all UI elements are properly translated
- Check for any hardcoded strings that should be moved to translation files