다국어 지원 웹을 만들기 위해 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는 정적 데이터만 취급된다는것 같다. 그러니 동적 설정을 사용하려면 완전히 다른 방법으로 접근해야 할것 같아 하드코딩으로 사용하기로 결정했다.
'실전코드 > JavaScript, VueJS' 카테고리의 다른 글
[Nuxt3] 운영 환경에서 콘솔 로그 노출 제한 (0) | 2025.01.10 |
---|---|
[Nuxt3] NuxtPage에 keepalive를 적용한 Tab형 화면 구현하기(Element Plus el-tabs) (0) | 2024.12.10 |