iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
Vue.js

Nuxt.js 3.x 筆記-打造 SSR 專案系列 第 22

D22:Nuxt 3.x 導入 I18n 實作多國語系

  • 分享至 

  • xImage
  •  

本篇文章同步更新於個人部落格,歡迎交流指教~謝謝您的閱讀

@nuxtjs/i18n 版本:v8.0.0-rc.3

多國語系讓我們的網站邁向國際市場,本篇將說明如何搭配 Nuxt3 整合模組 @nuxtjs/i18n 進行開發

@nuxtjs/i18n 簡介

  • 整合 Vue I18n
  • 自動產生路由
  • SEO 搜尋引擎最佳化
  • Lazy Loading 延遲載入
  • 自動偵測語言並切換
  • 多國語言支援不同域名

套件安裝

Nuxt3 需搭配 v8 版本,目前為 rc 版,透過 next tag 安裝

npm install -D @nuxtjs/i18n@next

nuxt.config 模組配置

// nuxt.config.js
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/i18n',
  ]
})

nuxt.config 設定模組選項

i18n module 完整選項參考 官方文件,以下範例配置:

  • strategy: 定義路由是否加上語系前綴,範例使用 prefix,所有語系都會加上路徑前綴(ex: http://localhost:3000/zh/

  • langDir: 翻譯檔目錄路徑,範例為根目錄下 locales/ 資料夾

  • locales: 語系選項,範例設定繁體中文英文,存放於 langDir 目錄下,以下範例檔結構:

    locales/
      |—— en.js
      |—— zh.js
    nuxt.config.js
    
  • defaultLocale: 預設語系

  • detectBrowserLanguage: 是否自動偵測使用者瀏覽器語系

    • useCookie: 設定為 true 將語系儲存於 cookie,避免使用者每次進入網站都重新導向
    • cookieKey: 預設 i18n_redirected
    • redirectOn: 設定為 root 根目錄,只在根目錄偵測語系,避免使用者進入網站時被重新導向,以利 SEO
// nuxt.config.js
export default defineNuxtConfig({
  i18n: {
    strategy: 'prefix',
    langDir: 'locales',
    locales: [
      {
        code: 'en',
        iso: 'en-US',
        file: 'en.js'
      },
      {
        code: 'zh',
        iso: 'zh-TW',
        file: 'zh.js'
      }
    ],
    defaultLocale: 'zh',
    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'i18n_redirected',
      redirectOn: 'root'
    }
  }
})

新增語系翻譯檔

路徑結構:

locales/
  |—— en.js
  |—— zh.js
// locales/en.js
export default {
  welcome: 'Welcome',
  backHome: 'Back Home',
  about: {
    title: 'About Us',
    description: 'This is About Page'
  }
};
// locales/zh.js
export default {
  welcome: '您好',
  backHome: '回首頁',
  about: {
    title: '關於我們',
    description: '這是關於我們頁面'
  }
};

多國語系基本應用

  • useLocalePath:依據當前語系解析路徑,EX:/about/zh/about
  • useSwitchLocalePath:用來切換語系
  • $t:Vue 實體方法,用來翻譯訊息
// pages/about.vue
<template>
  <div class="m-4">
    <NuxtLink :to="localePath('/')">{{ $t('backHome') }}</NuxtLink>

    <div>
      <NuxtLink :to="switchLocalePath('en')">English</NuxtLink>
      <NuxtLink :to="switchLocalePath('zh')">繁體中文</NuxtLink>
    </div>

    <h2>{{ $t('welcome') }}</h2>
    <h3>{{ $t('about.title') }}</h3>
    <p>{{ $t('about.description') }}</p>
  </div>
</template>

<script setup>
const localePath = useLocalePath();
const switchLocalePath = useSwitchLocalePath();
</script>

畫面呈現如下:


單一元件翻譯

前面說明如何建立各語系翻譯檔,也可以單獨在元件內透過 <i18n> 定義翻譯資訊

useScope: 'local't 方法作用域限制於元件內,這麼做可以避免受到全域翻譯檔影響

// pages/about.vue
<template>
  <div class="m-4">
    元件翻譯
    <h2>{{ t('welcome') }}</h2>

    全域翻譯
    <h2>{{ $t('welcome') }}</h2>
  </div>
</template>

<i18n lang="yaml">
  en:
    welcome: 'hello world'
  zh:
    welcome: '哈囉世界'
</i18n>

<script setup>
const { t } = useI18n({
  useScope: 'local'
});
</script>

全域翻譯檔

// locales/zh.js
export default {
  welcome: '您好'
};

畫面呈現如下:


插入動態變數

1. 具名變數

// pages/about.vue
<template>
  <h1>{{ t('hello', { name: 'Daniel' }) }}</h1>
</template>

<i18n lang="yaml">
  en:
    hello: 'hello {name}'
  zh:
    hello: '哈囉 {name}'
</i18n>

<script setup>
const { t } = useI18n({
  useScope: 'local'
});
</script>

2. 匿名變數(陣列)

// pages/about.vue
<template>
  <h1>{{ t('hello', [ 'Daniel' ]) }}</h1>
</template>

<i18n lang="yaml">
  en:
    hello: 'hello {0}'
  zh:
    hello: '哈囉 {0}'
</i18n>

// ...

<NuxtLinkLocale> 元件

等同於 <NuxtLink> 搭配 useLocalePath() Composable,以下兩個寫法編譯後結果相同

<template>
  <NuxtLinkLocale to="/">{{ $t('home') }}</NuxtLinkLocale>
</template>
<template>
  <NuxtLink :to="localePath('/')">{{ $t('home') }}</NuxtLink>
</template>

<script setup>
const localePath = useLocalePath();
</script>

SEO 優化

透過 useLocaleHead() 優化多國語系的 <head> 設定:

  • useLocaleHead:依據當前語系回傳 head 屬性
    • <html> 標籤 lang 屬性
    • hreflang 標籤屬性:告訴搜尋引擎頁面使用的語言,讓使用者在搜尋時,搜尋引擎能提供對應語言給用戶
    • og:locale 以及 og:locale:alternate 標籤
    • Canonical URL(標準網址)標籤:告訴搜尋引擎此頁面的主要連結,避免搜尋引擎處理重複內容網頁
  • addSeoAttributes:是否加上 SEO 屬性
  • useHead:Nuxt Composable,用來定義完整 <head> 標籤內容

Nuxt3 meta tags 相關配置可以參考 D16文章

// pages/about.vue
<template>
  <div>...</div>
</template>

<script setup>
const i18nHead = useLocaleHead({
  addSeoAttributes: true
});

useHead({
  htmlAttrs: {
    lang: i18nHead.value.htmlAttrs.lang
  },
  link: [ ...(i18nHead.value.link || []) ],
  meta: [ ...(i18nHead.value.meta || []) ]
});
</script>

產生的網頁原始碼:


參考資源:
https://v8.i18n.nuxtjs.org/
https://vue-i18n.intlify.dev/


上一篇
D21:Nuxt 3.x 狀態管理 State Management (3)-Pinia Plugin Persistedstate 維持狀態
下一篇
D23:Nuxt 3.x 替網站增加 Sitemap 網站地圖
系列文
Nuxt.js 3.x 筆記-打造 SSR 專案30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言