(VueJS) 다국어 처리

Javascript

  • TOC {:toc}

vue-i18n 설치하기

Installation

npm install --save vue-i18n

plugins/i18n.js

import Vue from 'vue';
import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

export default ({ app, store }) => {
  // Set i18n instance on app
  // This way we can use it in middleware and pages asyncData/fetch
  app.i18n = new VueI18n({
    // locale: store.state.locale,
    locale: 'ko',
    // fallbackLocale: 'ko',
    messages: {
      ko: require('~/locales/ko.json'),
    },
  });

  app.i18n.path = (link) => {
    if (app.i18n.locale === app.i18n.fallbackLocale) {
      return `/${link}`;
    }

    return `/${app.i18n.locale}/${link}`;
  };
};

locales/ko.json
locales 파일을 정의한다. 각 언어에 대하여 하나의 스크립트에 정의하는 것이 좋다.

{
  "index": {
    "meta": {
      "title": "Demo",
      "favicon": "favicon.ico"
    }
  }
}

nuxt.config.js
nuxt를 이용하는 경우에는 해당 플러그인 파일에 대하여 설정을 추가해준다.

plugins: [
  '~/plugins/i18n.js'
],

vue파일에서 키워드 호출하기
아래와 같은 형태로 사용하면 된다.

let title = this.$t('index.meta.title');
<p>{{ $t('index.meta.title') }}</p>

Tip

page에 따라서 동적으로 locale 파일을 읽어서 반영하기

페이지에서 사용하는 컴포넌트에서 해당 locale을 값을 공유하기 위해 store에 저장하여 관리하였음

// store/index.js
import Vuex from 'vuex';

export default () => {
  return new Vuex.Store({
    state: {
      locale: '',
    },
    mutations: {
      SET_SERVICE: (state, service) => {
        state.service = service;
      },
    },
  });
};

메인이 되는 페이지에서 페이지가 렌더링 되기 전의 시점에 locale 설정을 위해 아래와 같이 정의

// pages/index.vue
<script>
const SERVICE_KEY = 'index'
export default {
  name: 'Index',
  fetch ({ store }) {
    store.commit('SET_SERVICE', SERVICE_KEY)
  }
}
</script>

그리고 컴포넌트에서 store에서 꺼내어 사용하도록 하였다.

// layouts/default.vue
<template>
  <div id="app">
    <app-nav-bar
      :brand-logo-image="$t(service + '.navbar.brandLogo')"
      :brand-name="$t(service + '.navbar.brandName')"
      :aibril-logo-url="$t('aibrilLogo')"/>
    <b-container fluid>
      <nuxt/>
    </b-container>
    <app-footer/>
  </div>
</template>

<script>
import AppNavBar from '~/components/nav/AppNavBar.vue'
import AppFooter from '~/components/footer/AppFooter.vue'

import { mapState } from 'vuex'

export default {
  name: 'App',
  components: {
    AppNavBar,
    AppFooter
  },
  data () {
    return {
    }
  },
  computed: {
    ...mapState([
      'service'
    ])
  }
}
</script>

Reference

Nuxt-국제화 (i18n) Vue.js 다국어 처리하기