Summary
meta.title and meta.description are translated in every locale file but are never read anywhere in the codebase. frontend/index.html hardcodes the Chinese <title> and <meta name="description">, so the browser tab and the SEO description stay Chinese no matter which language the user selects.
Evidence
The keys exist and are translated in every locale:
en {'title': 'MiroFish - Predict Everything', 'description': 'MiroFish - Social Media Opinion Simulation System'}
zh {'title': 'MiroFish - 预测万物', 'description': 'MiroFish - 社交媒体舆论模拟系统'}
But nothing consumes them. Grepping the whole repo for meta.title, meta.description, t('meta, document.title, useHead and titleTemplate across frontend/ and backend/ returns no hits — the only meta. matches are Vite's own import.meta.glob (frontend/src/i18n/index.js:4) and import.meta.env (frontend/src/api/index.js:6).
Meanwhile frontend/index.html hardcodes both:
<meta name="description" content="MiroFish - 社交媒体舆论模拟系统" />
<title>MiroFish - 预测万物</title>
Reproduce
npm run dev
- Switch the UI language to English with the language switcher
- The page content becomes English, but the browser tab still reads MiroFish - 预测万物
Observed on main at 117ed37. It reproduces for any non-Chinese locale, so meta.* is currently two dead keys per locale file.
Impact
- The browser tab, bookmark name and window title are Chinese for every user, in every language
<meta name="description"> is Chinese, which is what search engines and link previews pick up
- Every locale file carries two translated keys that have no effect, which is misleading for anyone contributing a translation
Suggested fix
index.html already runs an inline script that reads the saved locale before Vue mounts, which is what makes html[lang] correct on first paint:
<script>document.documentElement.lang = localStorage.getItem('locale') || 'zh'</script>
The smallest fix that keeps that no-flash behaviour is to apply the title in App.vue (or main.js) from the existing i18n messages, and re-apply it whenever the locale changes — something along the lines of:
watchEffect(() => {
document.title = t('meta.title')
document.querySelector('meta[name="description"]')?.setAttribute('content', t('meta.description'))
})
That reuses the keys already present in every locale and needs no new dependency.
I'm happy to open a PR for this if you'd like — just let me know whether you'd prefer it handled in App.vue, in main.js, or by extending the existing inline script in index.html.
Context
Noticed while adding the Italian locale in #785. Not fixed there, to keep that PR scoped to the translation.
Suggested labels: enhancement, and possibly good first issue since the fix is small and self-contained (I don't have permission to set labels on this repo).
Summary
meta.titleandmeta.descriptionare translated in every locale file but are never read anywhere in the codebase.frontend/index.htmlhardcodes the Chinese<title>and<meta name="description">, so the browser tab and the SEO description stay Chinese no matter which language the user selects.Evidence
The keys exist and are translated in every locale:
But nothing consumes them. Grepping the whole repo for
meta.title,meta.description,t('meta,document.title,useHeadandtitleTemplateacrossfrontend/andbackend/returns no hits — the onlymeta.matches are Vite's ownimport.meta.glob(frontend/src/i18n/index.js:4) andimport.meta.env(frontend/src/api/index.js:6).Meanwhile
frontend/index.htmlhardcodes both:Reproduce
npm run devObserved on
mainat 117ed37. It reproduces for any non-Chinese locale, someta.*is currently two dead keys per locale file.Impact
<meta name="description">is Chinese, which is what search engines and link previews pick upSuggested fix
index.htmlalready runs an inline script that reads the saved locale before Vue mounts, which is what makeshtml[lang]correct on first paint:The smallest fix that keeps that no-flash behaviour is to apply the title in
App.vue(ormain.js) from the existing i18n messages, and re-apply it whenever the locale changes — something along the lines of:That reuses the keys already present in every locale and needs no new dependency.
I'm happy to open a PR for this if you'd like — just let me know whether you'd prefer it handled in
App.vue, inmain.js, or by extending the existing inline script inindex.html.Context
Noticed while adding the Italian locale in #785. Not fixed there, to keep that PR scoped to the translation.
Suggested labels: enhancement, and possibly good first issue since the fix is small and self-contained (I don't have permission to set labels on this repo).