Skip to content

다국어 POC

  1. i18n 라이브러리를 최소한으로 설정해서 만들어본 다국어 프로젝트
  2. 중국 프로젝트를 진행중이라 중국어와 한국어로 다국어 설정
  1. vite 프로젝트 생성

    Terminal window
    pnpm create vite
    .../198d62d3ef3-ef8 | +1 +
    .../198d62d3ef3-ef8 | Progress: resolved 1, reused 0, downloaded 1, added 1, done
    |
    o Project name:
    | poc-i18n
    |
    o Select a framework:
    | React
    |
    o Select a variant:
    | TypeScript + SWC
    |
    o Scaffolding project in D:\study\poc-i18n...
    |
    — Done. Now run:
    cd poc-i18n
    pnpm install
    pnpm run dev
  2. git 저장소 설정

    Terminal window
    cd poc-i18n
    git init
  • i18next

    Terminal window
    pnpm install i18next react-i18next
  • @types/node

    Terminal window
    pnpm install --save-dev @types/node
  • TailwindCSS

    Terminal window
    pnpm install tailwindcss @tailwindcss/vite
  • DaisyUI

    Terminal window
    pnpm add -D daisyui@latest
  • Prettier

    Terminal window
    pnpm add --save-dev --save-exact prettier
    pnpm install -D prettier-plugin-tailwindcss
  • vite-tsconfig-paths

    Terminal window
    pnpm add -D vite-tsconfig-paths
  • .prettierrc.cjs
  • eslint.config.js
  • tsconfig.app.json
  • vite.config.ts
  • src/index.css
  • Directorysrc
    • Directoryhook
      • index.ts
      • useLocale.ts
    • Directorylocales
      • i18n.ts
      • Directoryko
        • main_ko.json
      • Directoryzh
        • main_zh.json
    • Directoryutils
      • index.ts
  • App.tsx
  • main.tsx
src/locales/ko/main_ko.json
{
"apple": "사과",
"banana": "바나나",
"cherry": "체리"
}
src/locales/zh/main_zh.json
{
"apple": "苹果",
"banana": "香蕉",
"cherry": "樱桃"
}
src/locales/i18n.ts
import i18n from 'i18next'
import {initReactI18next} from 'react-i18next'
import mainKo from './ko/main_ko.json'
import mainZh from './zh/main_zh.json'
const resources = {
ko: {
translation: mainKo,
},
zh: {
translation: mainZh,
},
}
i18n.use(initReactI18next).init({
resources,
lng: 'ko',
fallbackLng: 'ko',
interpolation: {
escapeValue: false,
},
})
export default i18n
src/utils/index.ts
export const isNull = <T>(value: T): boolean => value === undefined || value === null
export const createArray = (count: number): number[] =>
[...Array(count).keys()].map((i) => i)
export const range = (start: number, end: number): number[] => {
if (end > start) {
return createArray(end - start).map((i) => i + start)
}
return []
}
export const applyParam = (value: string, params?: string[]) => {
let buffer = value
if (params && params.length > 0) {
range(0, params.length).forEach((i) => {
const key = `{${i}}`
buffer = buffer.replace(key, params[i])
})
}
return buffer
}
src/hook/useLocale.ts
import {applyParam, isNull} from '@/utils'
import {useTranslation} from 'react-i18next'
export const useLocale = () => {
const {i18n, t} = useTranslation()
const getLanguage = () => i18n.language
const changeLanguage = (langCd: string) => {
i18n.changeLanguage(langCd)
}
const getMessage = (key: string, params: string[]) => {
if (isNull(t)) {
return ''
}
const buffer = t(key)
return applyParam(buffer, params)
}
return {
getLanguage,
changeLanguage,
getMessage,
}
}
src/hook/index.ts
export * from './useLocale'
src/App.tsx
import './App.css'
import {useLocale} from '@/hook'
import {useEffect} from 'react'
const App = () => {
const {getMessage, getLanguage, changeLanguage} = useLocale()
useEffect(() => {
const language = getLanguage()
if (language !== 'ko' && language !== 'zh') {
changeLanguage('zh')
}
}, [])
return (
<div className="flex h-screen w-screen flex-col bg-white">
<div className="m-2">
<button className="btn btn-primary mr-3" onClick={() => changeLanguage('ko')}>
한국어
</button>
<button className="btn btn-primary mr-3" onClick={() => changeLanguage('zh')}>
중국어
</button>
</div>
<div>
<div className="text-black">{getMessage('apple', [])}</div>
<div className="text-black">{getMessage('banana', [])}</div>
<div className="text-black">{getMessage('cherry', [])}</div>
</div>
</div>
)
}
export default App
src/main.tsx
import {StrictMode} from 'react'
import {createRoot} from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import {I18nextProvider} from 'react-i18next'
import i18n from './locales/i18n.ts'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<I18nextProvider i18n={i18n}>
<App />
</I18nextProvider>
</StrictMode>,
)
  1. 버튼을 클릭하면 언어가 변경된다. image image