
Nuxt에서 다국어 구성하기
Nuxt안녕하세요 Lovefield입니다.
이번 글은 다국어에 관한 글입니다. 많은 분이 다국어라고 하면 i18n 라이브러리를 떠올리실 텐데요. 개인적으로 라이브러리를 사용하지 않습니다. 이유는 간단합니다, 라이브러리를 쓸 정도의 기술이라고 생각하지 않기 때문입니다. 오히려 원하는 기능을 추가해 사용할 수 있기 때문에 직접 구현해서 사용하는 편입니다.
다국어의 원리는 간단합니다. 언어별로 텍스트를 구성한 다음 설정된 언어에 맞게 텍스트를 불러오면 됩니다. 이를 구현하기 위해서 Nuxt의 store, utils, middleware를 사용합니다.
가장먼저 store를 생성해줍니다. 사이트의 전반적인 설정을 담고 있어야 하며 그중 언어 부분을 사용하게 될 겁니다.
stores/siteStore.ts
TypeScript
export const useSiteStore = defineStore("siteStore", {
state: (): => ({
language: "en-US",
}),
actions: {
setLanguage(value: string) {
this.language = value;
},
},
});
store가 구성되었으니 middleware에서 사이트에 접속할 때 header를 기반으로 언어를 지정합니다. 전역으로 실행되어야 하니 파일명에 유의해주세요.
middleware/application.global.ts
TypeScript
export default defineNuxtRouteMiddleware(async (to, from) => {
const siteStore = useSiteStore();
if (import.meta.server === true) {
const header = useRequestHeaders();
if (header["accept-language"] !== undefined) {
const language: string = header["accept-language"].split(",")[0];
siteStore.setLanguage(language === "ko-KR" ? "ko-KR" : "en-US");
} else {
siteStore.setLanguage("en-US");
}
}
});
최상위 폴더에 language 폴더를 생성한 다음 ko.json 과 en.json 파일을 생성해줍니다. 각각 한글과 영문으로 작성된 정보를 가지고 있어야 합니다.
language/ko.json
JSON
{
“site”: {
“title”: “Dico - 말하다, 표현하다”,
“description”: “개발자 부부가 개발과 일상을 기록하는 블로그입니다. 정보의 바다에서 여기 Dico라는 섬을 발견하셨다면, 개발자 부부가 만들어가는 작은 섬들을 재미있게 둘러봐 주시면 좋겠습니다.”
}
}
language/en.json
JSON
{
“site”: {
“title”: “Dico - Speak, Manifest”
“description”: “It's a blog where the developer couple records their development and their daily lives. If you've discovered an island here called Dico in the Sea of Information, I hope you enjoy taking a look at the little islands that the developer couple is building.”
}
}
type도 지정합니다. 이는 함수에 넣을 키를 좀 더 쉽게 하기 위한 편의 사항입니다. `nuxt.config.ts` 에서 import 설정이 되어있어야 한다는 점 유의해주세요.
types/language.ts
TypeScript
type LanguageKey = “site.title” | “site.description”;
마지막으로 utils를 작성합니다. 실질적으로 `ko.json` 과 `en.json`에서 텍스트를 가져와 반환하는 역할을 합니다.
utils/getTextContent.ts
TypeScript
import ko from "@/language/ko.json";
import en from "@/language/en.json";
export const _getTextContent = (key: LanguageKey): string => {
const siteStore = useSiteStore();
const keyList: string[] = key.split(".");
let target: any = {};
if (siteStore.language === "ko-KR") {
target = ko;
} else {
target = en;
}
return getTextLogic(target, keyList);
};
function getTextLogic(target: any, keyList: string[]): string {
if (target[keyList[0]] !== undefined) {
if (keyList.slice(1).length > 0) {
return getTextLogic(target[keyList[0]], keyList.slice(1));
} else {
return target[keyList[0]];
}
} else {
return "";
}
}
모든 설정이 끝났습니다. 페이지에서는 다음과 같이 사용 가능합니다.
pages/index.vue
HTML, XML
<template>
<p class=”text”>{{ _getTextContent(“site.title”) }}</p>
</template>