Skip to content

meta.title and meta.description are translated but never applied - browser tab stays Chinese in every language #786

Description

@SandroHub013

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

  1. npm run dev
  2. Switch the UI language to English with the language switcher
  3. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions