본문 바로가기

실전코드/JavaScript, VueJS

Nuxt3 에서 다국어 기능(locale) 멀티 파일 적용해서 사용하기 (nuxtjs/i18n)

728x90
반응형

다국어 지원 웹을 만들기 위해 i18n을 도입하기로 하였다.

Nuxt3를 공식 지원하는 nuxtjs/i18n 라이브러리를 사용하게 되었다.

 

@nuxtjs/i18n

Internationalization for Nuxt. Latest version: 9.1.0, last published: 17 days ago. Start using @nuxtjs/i18n in your project by running `npm i @nuxtjs/i18n`. There are 89 other projects in the npm registry using @nuxtjs/i18n.

www.npmjs.com

npm에서 확인해보면 다운로드 수도 많고 업데이트도 꾸준히 되고 있는 듯 하다.

vue-i18n을 기반으로 만들어졌다고 하며, vue-i18n을 nuxt3에서 직접 사용하면 라우터 설정부터 해서 이것저것 신경쓸게 많다보니 역시나 nuxtjs/i18n을 사용하는게 좋다고 판단했다.

 

설치

 

Internationalization for Nuxt Applications · @nuxtjs/i18n

I18n (Internationalization) module for your Nuxt project powered by Vue I18n.

i18n.nuxtjs.org

라이브러리 설치

npx nuxi@latest module add @nuxtjs/i18n@next

nuxt.config.ts에 modules 추가

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n']
})

nuxt.config.ts에 i18n 설정 추가

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    // Module Options
  }
})

공식 문서대로 적용해 봤는데 eslint를 사용하니 i18n은 defineNuxtConfig에서 미리 지정한 프로퍼티가 아니라며 빨간줄이 뜬다.

이를 해결하기 위해 i18n config 파일을 따로 만들어서 import 하는 방법을 적용시켰다.

config/i18n.config.ts

export default {
    // Module Options
}
// 위치나 파일명은 임의로 설정 가능

nuxt.config.ts

import i18n from './config/i18n.config'

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

기본 설정

config/i18n.config.ts

export default {
  legacy: false,			// composition API 사용을 위해 설정
  locales: [
    { code: 'ko', name: '한글', iso: 'ko-KR', file: 'ko.json' },
    { code: 'en', name: 'English', iso: 'en-US', file: 'en.json' },
  ],
  defaultLocale: 'ko',
  langDir: './',			// locales에 설정한 file의 위치 설정, 루트 디렉터리는 i18n으로 설정됨
  strategy: 'no_prefix',		// url에 ko, en 등 prefix 쓸지 안쓸지 설정
  lazy: true,
  detectBrowserLanguage: {		// cookie 사용해서 locale 정보 저장
    useCookie: true,
    cookieKey: 'i18n_redirected',
  },
}

i18n/ko.json

{
  "api": {
    "apiSample": "API Sample(en)"
  }
}

i18n/en.json

{
  "api": {
    "apiSample": "API 샘플(ko)"
  }
}

lagDir에 설정한 ./은 자동적으로 루트 디렉터리에 만들어진 i18n에서부터 찾는다. i18n 디렉터리를 만들어서 그 안에 locale json 파일을 넣어 두어야 한다.

사용

<template>
    <div>
    	{{ t('api.apiSample') }}
    </div>
</template>

<script setup lang="ts">
const { t } = useI18n()
</script>

locale select box 생성

<template>
    <div>
        <el-select v-model="lang" class="select-lang" @change="onChangeLocale">
          <el-option
            v-for="(item, idx) in locales"
            :key="idx"
            :label="item.name"
            :value="item.code"
          />
        </el-select>
    </div>
</template>

<script setup lang="ts">
const { locales, locale } = useI18n()
const lang = ref(locale.value)

const onChangeLocale = (val: string) => {
  document.cookie = `i18n_redirected=${val};path=/`
  useRouter().go(0)
}
</script>

 

셀렉트 박스에서 locale정보에서 설정한 name을 선택해 주면 해당 언어로 json에 저장된 데이터가 표시되는걸 알 수 있다.

json 파일을 잘 정리해가며 사용하면 좋을거 같지만 규모가 큰 프로젝트에서 여러명이 협업을 하다보면 어마어마한 파일의 크기와 충돌을 예상할 수 있다. 따라서 하나의 언어를 여러개의 파일로 관리해 적용하는 방법을 적용시켜 보았다.

멀티파일 적용

config/i18n.config.ts 에서 locales에 files만 설정해주면 된다.

i18n
├ ko
│ ├ api.json
│ └ grid.json
└ en
  ├ api.json
  └ grid.json
export default {
  locales: [
    { code: 'ko', name: '한글', iso: 'ko-KR', files: ['ko/api.json', 'ko/grid.json'] },
    { code: 'en', name: 'English', iso: 'en-US', files: ['en/api.json', 'en/grid.json']},
  ],
}

위와 같은 방법으로 하면 Nuxt3가 빌드될 때  files에 등록된 json 파일들이 하나의 파일로 오버라이드 된다. 따라서 각각의 파일을 구분할 필요 없이 하나의 파일 안의 json 데이터인 것 처럼 $t() 함수를 사용하면 된다.

추가적으로 files에 들어갈 배열값을 동적으로 만들어보려고 노력했으나, 기본적으로 nuxt.config.ts는 정적 데이터만 취급된다는것 같다. 그러니 동적 설정을 사용하려면 완전히 다른 방법으로 접근해야 할것 같아 하드코딩으로 사용하기로 결정했다.

728x90
반응형