For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Allow admin to configure a global default language in System Settings, which is forced for unauthenticated users and logged-in users without a personal language preference.
Architecture: Backend adds a DefaultLanguage option to the existing flat-key option system (same pattern as SystemName, ServerAddress). The value flows to frontend via /api/status. Frontend applies it in two places: PageLayout.jsx (for unauthenticated users) and UserContext (for logged-in users without preference).
Tech Stack: Go (backend), React + Semi UI (frontend), i18next (i18n)
Spec: docs/superpowers/specs/2026-04-17-default-language-setting-design.md
| File | Action | Responsibility |
|---|---|---|
common/constants.go |
Modify | Declare DefaultLanguage variable |
model/option.go |
Modify | Handle DefaultLanguage in option update switch |
controller/misc.go |
Modify | Expose default_language in /api/status response |
web/src/components/settings/SystemSetting.jsx |
Modify | Admin UI: language dropdown in system settings |
web/src/components/layout/PageLayout.jsx |
Modify | Apply default language for unauthenticated users |
web/src/context/User/index.jsx |
Modify | Fall back to default language when user has no preference |
Files:
Modify: common/constants.go:17-18 (after TopUpLink declaration)
Modify: model/option.go:457-458 (after Logo case in updateOptionMap switch)
In common/constants.go, after line 18 (var TopUpLink = ""), add:
var DefaultLanguage = "" // admin-configured default language; empty = follow browser detection
In model/option.go, after the case "Logo": block (line 457-458), add:
case "DefaultLanguage":
common.DefaultLanguage = value
Run: go build ./...
Expected: no errors
git add common/constants.go model/option.go
git commit -m "feat(default-language): add DefaultLanguage variable and option handler"
Files:
Modify: controller/misc.go:89 (after "default_use_auto_group" line)
In controller/misc.go, inside GetStatus(), after the line containing "default_use_auto_group": setting.DefaultUseAutoGroup, (line 89), add:
"default_language": common.DefaultLanguage,
Place it right before the blank line at line 90, aligned with the surrounding entries.
Run: go build ./...
Expected: no errors
git add controller/misc.go
git commit -m "feat(default-language): expose default_language in /api/status response"
Files:
Modify: web/src/components/settings/SystemSetting.jsx
In web/src/components/settings/SystemSetting.jsx, in the inputs useState (around line 49-112), add DefaultLanguage: '' after ServerAddress: '' (line 102):
ServerAddress: '',
DefaultLanguage: '',
After submitServerAddress (line 315-318), add a new function:
const submitDefaultLanguage = async () => {
await updateOptions([{ key: 'DefaultLanguage', value: inputs.DefaultLanguage || '' }]);
};
In the 通用设置 Form.Section (line 715-733), inside the <Row> block, after the ServerAddress <Col> closing tag (line 728) and before the </Row> closing tag (line 729), add a new <Col>:
<Col xs={24} sm={24} md={24} lg={12} xl={12}>
<Form.Select
field='DefaultLanguage'
label={t('默认语言')}
placeholder={t('未设置时跟随浏览器语言')}
optionList={[
{ label: t('自动(跟随浏览器)'), value: '' },
{ label: '简体中文', value: 'zh-CN' },
{ label: '繁體中文', value: 'zh-TW' },
{ label: 'English', value: 'en' },
{ label: 'Français', value: 'fr' },
{ label: '日本語', value: 'ja' },
{ label: 'Русский', value: 'ru' },
{ label: 'Tiếng Việt', value: 'vi' },
]}
extraText={t(
'设置后,未登录用户和未设置语言偏好的已登录用户将强制使用此语言',
)}
/>
</Col>
Also change the ServerAddress Col from md={24} lg={24} xl={24} to md={24} lg={12} xl={12} so both fields sit side by side on large screens.
After the existing submitServerAddress button (line 730-732), add:
<Button onClick={submitDefaultLanguage}>
{t('保存默认语言')}
</Button>
Run: cd web && bun run build
Expected: build succeeds
git add web/src/components/settings/SystemSetting.jsx
git commit -m "feat(default-language): add language dropdown in system settings"
Files:
Modify: web/src/components/layout/PageLayout.jsx:87-100 (loadStatus function)
In web/src/components/layout/PageLayout.jsx, in the loadStatus function (line 87-100), after setStatusData(data) (line 93) and before the } else { (line 94), add:
// Apply admin-configured default language for unauthenticated users
if (data.default_language && !localStorage.getItem('user')) {
i18n.changeLanguage(data.default_language);
}
In the same file, the existing useEffect (line 102-120) reads localStorage.getItem('i18nextLng') and calls i18n.changeLanguage(savedLang). This logic should be kept as-is — it handles the case where default_language is not set (admin chose “auto”). No changes needed to this block.
Run: cd web && bun run build
Expected: build succeeds
git add web/src/components/layout/PageLayout.jsx
git commit -m "feat(default-language): apply default language for unauthenticated users"
Files:
Modify: web/src/context/User/index.jsx:20-45
At the top of web/src/context/User/index.jsx, add StatusContext import after the existing imports:
import { StatusContext } from '../Status';
Inside UserProvider (line 29), before the useEffect, add:
const [statusState] = React.useContext(StatusContext);
Replace the existing useEffect (lines 34-45) with:
// Sync language preference when user data is loaded
useEffect(() => {
if (state.user?.setting) {
try {
const settings = JSON.parse(state.user.setting);
if (settings.language && settings.language !== i18n.language) {
i18n.changeLanguage(settings.language);
} else if (!settings.language && statusState.status?.default_language) {
// No personal preference — fall back to admin default
i18n.changeLanguage(statusState.status.default_language);
}
} catch (e) {
// Ignore parse errors
}
}
}, [state.user?.setting, statusState.status?.default_language, i18n]);
Run: cd web && bun run build
Expected: build succeeds
git add web/src/context/User/index.jsx
git commit -m "feat(default-language): fall back to default language for users without preference"
Terminal 1: cd web && bun run dev
Terminal 2: go run main.go
curl -s http://localhost:3000/api/status | python -m json.tool | grep default_language
Expected: "default_language": "en" (or the set value, or "" if auto)