登录

Nuxt的国际化终极解决方案:I18n+Nuxt Content

作者:neo yang 时间:2023/12/06 读: 7674
出海大潮,国内用得很多的Vue和Nuxt也经常要面对国际化的问题。 如果是wordpress的话,就简单了,装 […]

出海大潮,国内用得很多的Vue和Nuxt也经常要面对国际化的问题。

如果是wordpress的话,就简单了,装一个插件,配置好Google的翻译接口,然后系统就会每天将新的内容自动翻译成各种语言版本。

但对于其它的系统,就不那么方便了。

代码已开源:https://github.com/aigc-projects/nuxt-i18n-starter

一、基本的国际化——I18n

nuxt-i18n

1、什么是I18n?

I18n是Nuxt国际化的必须的东西。它主要是提供了一套完整的国际化的解决方案,包括国际化路由、和基于国际化路由改变语言的方法。

2、安装I18n

以下都可以。

yarn add @nuxtjs/i18n # yarn
npm i @nuxtjs/i18n # npm
pnpm i @nuxtjs/i18n 
pnpm add @nuxtjs/i18n@next --save-dev

3、配置nuxt.config.ts

 modules: [
     '@nuxtjs/i18n',  
  ], 
   i18n: {
      locales: [
          { name: "English",code: "en", iso: "en-US", dir: "ltr" },
          { name: "español",code: "es", iso: "es-LA", dir: "ltr" },
          { name: "En français",code: "fr", iso: "fr-FR", dir: "ltr" },
          { name: "العربية",code: "ar", iso: "ar-EG", dir: "rtl" },],
      defaultLocale: "en",
      detectBrowserLanguage: false,
     // 👇 Reference the Vue I18n config file
     vueI18n: "./i18n.config.js",
    }, 

4、配置i18n.config.ts

新建i18n.config.ts或i18n.config.js

这个文件是用来配置翻译字段的。

export default defineI18nConfig(() => ({
  legacy: false,
  // 👇 Add translations
  messages: {
    "en": {
      nav_about: "About",
    },

    "es": {
      nav_about: "sobre",
    },
    "ar": {
      nav_about: "نبذة عنا",
    },
    "fr": {
      nav_about: "About",
    },

  },
}))

5、链接组件

代码

<!-- components/LocLink.vue -->

<script setup lang="ts">
defineProps(["to"])

const localePath = useLocalePath()
</script>

<template>
  <NuxtLink :to="localePath(to)"><slot /></NuxtLink>
</template>

用法

<LocLink to="/">{{ $t('nav_home') }}</LocLink>

6、语言切换组件

代码

<!-- components/LangSwitcher.vue -->

<script setup lang="ts">
// Used for type casting
// Used for type casting
import type { LocaleObject } from "@nuxtjs/i18n/dist/runtime/composables";

// Get active locale and supported locales
const { locale, locales } = useI18n()
// Cast to avoid TypeScript errors in template
const supportedLocales = locales.value as Array<LocaleObject>

const router = useRouter()
const switchLocalePath = useSwitchLocalePath()

// When the visitor selects a new locale, route to
// to the new locale's path e.g. /en-CA/foo → /ar-EG/foo
function onLocaleChanged(event: Event) {
  const target = event.target as HTMLInputElement
  
  // switchLocalePath('ar-EG') will return Arabic equivalent
  // for the *current* URL path e.g. if we're at /en-CA/about,
  // switchLocalePath('ar-EG') will return '/ar-EG/about'
  router.push({ path: switchLocalePath(target.value) })
}
</script>

<template>
  <div>
    🌐
    <select :value="locale" @change="onLocaleChanged">
      <option v-for="loc in supportedLocales" :key="loc.code" :value="loc.code">
        {{ loc.name }}
      </option>
    </select>
  </div>
</template>

用法

在页面或布局中使用标签:<LangSwitcher />

7、获取当前的语言

context.app.i18n.locale // where you have access to NuxtContext
this.$i18n.locale //in component
$i18n.locale  // in template

二、文档内容的国际化

单独使用I18n完全可以实现全站的国际化。但如果网站有很多文章,那么就需要在i18n.config.ts中写入大量的配置项,相当麻烦。

当然,如果文章内容来源于后端数据库,那么就不用考虑这个了,只需要将翻译好的内容存入数据库,不同的语言页面取相应语言的文章版本就可以了。

这里说的是,文章内容没有在后端数据库,而是放在前端。

对于nuxt来说,最好的方法就是使用nuxt content。简单地说,就是将文章都存在markdown文件中,然后,打开某个路由就会加载这个路由对应的页面和markdown文件。

因为同样的页面,比如首页,不同的语言,使用的路由是不同的。

比如,默认英语。首页是www.xxx.com, 西班牙语版就是www.xxx.com/es。

所以www.xxx.com会调用pages目录下的index.vue,并加载content目录下的index.md。而,www.xxx.com/es会调用pages目录下的index.vue,并加载content目录下的es.md文档。

所以,对同一篇文章的不同语言的版本,只需要在content目录下按照路由建相应版本的翻译文件即可。

1、安装nuxt content

pnpm add @nuxt/content

2、nuxt.config.ts配置

modules: [
    '@nuxt/content'
  ],
  content: {
    // ... options
  }

3、在页面调用相应翻译文档

首页默认英语,配置西班牙语路由和页面。

最后的路由是这样的:

默认首页(英语):www.xxx.com

西班牙语首页:www.xxx.com/es

首先,设计content的文件目录

//content目录设计
|
pages
. index.vue
content
. index.md
. es.md

然后,在首页中需要调用文章的部分加标签

 <ContentDoc />

三、国际化路由的最佳实践

en-US,en表示英语,US表示国家:美国。这是一个标准的语言代码。路由可以直接这样来写:www.xxx.com/en-US

但是,大多时候,我们不需要细分到国家的层次,只需要到语言的层次就够了。所以,这样写,反而是最合适的:www.xxx.com/en

当然,对于中文,就不能这样了,中文有:zh-CN(简体中文),zh-HK(香港繁体),zh-TW(台湾繁体)

所以,对于中文,只能这样:www.xxx.com/zh-cn

四、附录:国际标准的语言代码

语言代码语言国家
af南非语
af-ZA南非语
ar阿拉伯语
ar-AE阿拉伯语(阿联酋)
ar-BH阿拉伯语(巴林)
ar-DZ阿拉伯语(阿尔及利亚)
ar-EG阿拉伯语(埃及)
ar-IQ阿拉伯语(伊拉克)
ar-JO阿拉伯语(约旦)
ar-KW阿拉伯语(科威特)
ar-LB阿拉伯语(黎巴嫩)
ar-LY阿拉伯语(利比亚)
ar-MA阿拉伯语(摩洛哥)
ar-OM阿拉伯语(阿曼)
ar-QA阿拉伯语(卡塔尔)
ar-SA阿拉伯语(沙特阿拉伯)
ar-SY阿拉伯语(叙利亚)
ar-TN阿拉伯语(突尼斯)
ar-YE阿拉伯语(也门)
az阿塞拜疆语
az-AZ阿塞拜疆语(拉丁文)
az-AZ阿塞拜疆语(西里尔文)
be比利时语
be-BY比利时语
bg保加利亚语
bg-BG保加利亚语
bs-BA波斯尼亚语(拉丁文,波斯尼亚和黑塞哥维那)
ca加泰隆语
ca-ES加泰隆语
cs捷克语
cs-CZ捷克语
cy威尔士语
cy-GB威尔士语
da丹麦语
da-DK丹麦语
de德语
de-AT德语(奥地利)
de-CH德语(瑞士)
de-DE德语(德国)
de-LI德语(列支敦士登)
de-LU德语(卢森堡)
dv第维埃语
dv-MV第维埃语
el希腊语
el-GR希腊语
en英语
en-AU英语(澳大利亚)
en-BZ英语(伯利兹)
en-CA英语(加拿大)
en-CB英语(加勒比海)
en-GB英语(英国)
en-IE英语(爱尔兰)
en-JM英语(牙买加)
en-NZ英语(新西兰)
en-PH英语(菲律宾)
en-TT英语(特立尼达)
en-US英语(美国)
en-ZA英语(南非)
en-ZW英语(津巴布韦)
eo世界语
es西班牙语
es-AR西班牙语(阿根廷)
es-BO西班牙语(玻利维亚)
es-CL西班牙语(智利)
es-CO西班牙语(哥伦比亚)
es-CR西班牙语(哥斯达黎加)
es-DO西班牙语(多米尼加共和国)
es-EC西班牙语(厄瓜多尔)
es-ES西班牙语(传统)
es-ES西班牙语(国际)
es-GT西班牙语(危地马拉)
es-HN西班牙语(洪都拉斯)
es-MX西班牙语(墨西哥)
es-NI西班牙语(尼加拉瓜)
es-PA西班牙语(巴拿马)
es-PE西班牙语(秘鲁)
es-PR西班牙语(波多黎各(美))
es-PY西班牙语(巴拉圭)
es-SV西班牙语(萨尔瓦多)
es-UY西班牙语(乌拉圭)
es-VE西班牙语(委内瑞拉)
et爱沙尼亚语
et-EE爱沙尼亚语
eu巴士克语
eu-ES巴士克语
fa法斯语
fa-IR法斯语
fi芬兰语
fi-FI芬兰语
fo法罗语
fo-FO法罗语
fr法语
fr-BE法语(比利时)
fr-CA法语(加拿大)
fr-CH法语(瑞士)
fr-FR法语(法国)
fr-LU法语(卢森堡)
fr-MC法语(摩纳哥)
gl加里西亚语
gl-ES加里西亚语
gu古吉拉特语
gu-IN古吉拉特语
he希伯来语
he-IL希伯来语
hi印地语
hi-IN印地语
hr克罗地亚语
hr-BA克罗地亚语(波斯尼亚和黑塞哥维那)
hr-HR克罗地亚语
hu匈牙利语
hu-HU匈牙利语
hy亚美尼亚语
hy-AM亚美尼亚语
id印度尼西亚语
id-ID印度尼西亚语
is冰岛语
is-IS冰岛语
it意大利语
it-CH意大利语(瑞士)
it-IT意大利语(意大利)
ja日语
ja-JP日语
ka格鲁吉亚语
ka-GE格鲁吉亚语
kk哈萨克语
kk-KZ哈萨克语
kn卡纳拉语
kn-IN卡纳拉语
ko朝鲜语
ko-KR朝鲜语
kok孔卡尼语
kok-IN孔卡尼语
ky吉尔吉斯语
ky-KG吉尔吉斯语(西里尔文)
lt立陶宛语
lt-LT立陶宛语
lv拉脱维亚语
lv-LV拉脱维亚语
mi毛利语
mi-NZ毛利语
mk马其顿语
mk-MK马其顿语(FYROM)
mn蒙古语
mn-MN蒙古语(西里尔文)
mr马拉地语
mr-IN马拉地语
ms马来语
ms-BN马来语(文莱达鲁萨兰)
ms-MY马来语(马来西亚)
mt马耳他语
mt-MT马耳他语
nb挪威语(伯克梅尔)
nb-NO挪威语(伯克梅尔)(挪威)
nl荷兰语
nl-BE荷兰语(比利时)
nl-NL荷兰语(荷兰)
nn-NO挪威语(尼诺斯克)(挪威)
ns北梭托语
ns-ZA北梭托语
pa旁遮普语
pa-IN旁遮普语
pl波兰语
pl-PL波兰语
pt葡萄牙语
pt-BR葡萄牙语(巴西)
pt-PT葡萄牙语(葡萄牙)
qu克丘亚语
qu-BO克丘亚语(玻利维亚)
qu-EC克丘亚语(厄瓜多尔)
qu-PE克丘亚语(秘鲁)
ro罗马尼亚语
ro-RO罗马尼亚语
ru俄语
ru-RU俄语
sa梵文
sa-IN梵文
se北萨摩斯语
se-FI北萨摩斯语(芬兰)
se-FI斯科特萨摩斯语(芬兰)
se-FI伊那里萨摩斯语(芬兰)
se-NO北萨摩斯语(挪威)
se-NO律勒欧萨摩斯语(挪威)
se-NO南萨摩斯语(挪威)
se-SE北萨摩斯语(瑞典)
se-SE律勒欧萨摩斯语(瑞典)
se-SE南萨摩斯语(瑞典)
sk斯洛伐克语
sk-SK斯洛伐克语
sl斯洛文尼亚语
sl-SI斯洛文尼亚语
sq阿尔巴尼亚语
sq-AL阿尔巴尼亚语
sr-BA塞尔维亚语(拉丁文,波斯尼亚和黑塞哥维那)
sr-BA塞尔维亚语(西里尔文,波斯尼亚和黑塞哥维那)
sr-SP塞尔维亚(拉丁)
sr-SP塞尔维亚(西里尔文)
sv瑞典语
sv-FI瑞典语(芬兰)
sv-SE瑞典语
sw斯瓦希里语
sw-KE斯瓦希里语
syr叙利亚语
syr-SY叙利亚语
ta泰米尔语
ta-IN泰米尔语
te泰卢固语
te-IN泰卢固语
th泰语
th-TH泰语
tl塔加路语
tl-PH塔加路语(菲律宾)
tn茨瓦纳语
tn-ZA茨瓦纳语
tr土耳其语
tr-TR土耳其语
ts宗加语
tt鞑靼语
tt-RU鞑靼语
uk乌克兰语
uk-UA乌克兰语
ur乌都语
ur-PK乌都语
uz乌兹别克语
uz-UZ乌兹别克语(拉丁文)
uz-UZ乌兹别克语(西里尔文)
vi越南语
vi-VN越南语
xh班图语
xh-ZA班图语
zh中文
zh-CN中文(简体)
zh-HK中文(香港)
zh-MO中文(澳门)
zh-SG中文(新加坡)
zh-TW中文(繁体)
zu祖鲁语
zu-ZA祖鲁语

链接

https://github.com/aigc-projects/nuxt-i18n-starter



copyright © www.lyustu.com all rights reserve.
Theme: TheMoon V3.0. Author:neo yang